0

我有一个难题。

我的数据有一个 ID、一个分组键、一个标签和第二个标签。看起来有点像这样

|----|----------|-------|------|
|id  |group_col |label1 |label2|
|--- |----------|-------|------|
|1   | 1        | abcd  | 123  |
|2   | 1        | nfrv  | 123  |
|3   | 2        | dfgd  |      |
|4   | 3        | kgff  | 899  |
|5   | 3        | kgff  | 899  |
|6   | 3        | ygoi  |      |
|7   | 4        | tgfo  |      |
|8   | 4        | tgfo  |      |  
|----|----------|-------|------|

现在我的挑战是在每个组中检查两个人是否具有相同的 label2 值,如果是,则将其传播给该组的所有成员。并且另外为整个组(最好是第一个人)设置相同的 label1 值(如果人们有想法,也可以在新列中)。

预期的输出应该是这样的:

|----|----------|-------|------|------------|
|id  |group_col |label1 |label2| label1_new |
|--- |----------|-------|------|------------|
|1   | 1        | abcd  | 123  | abcd       |
|2   | 1        | abcd  | 123  | abcd       |
|3   | 2        | dfgd  |      | dfgd       |
|4   | 3        | kgff  | 899  | kgff       | 
|5   | 3        | kgff  | 899  | kgff       |  
|6   | 3        | ygoi  | 899  | kgff       |  
|7   | 4        | tgfo  |      | tgfo       |  
|8   | 4        | tgfo  |      | tgfo       |  
|----|----------|-------|------|------------|

另外请注意,这将必须在数百万行/组上运行,因此应该尽可能高效

谢谢你的帮助

4

2 回答 2

0

实际上,我之前有点脑电波,并想出了一个可能的解决方案。还没有在大型数据喷气机上测试过,也没有清理过(稍后会这样做)。但如果有人有更好的方法,我很想听听。

df = pd.DataFrame(np.array([[1,1,'abcd',123],
                  [2,1,'nfrv',123],
                  [3,2,'dfgd',''],
                  [4,3,'kgff',899],
                  [5,3,'kgff',899],
                  [6,3,'ygoi',''],
                  [7,4,'tgfo',''],
                  [8,4,'tgfo',''],
                  [9,5,'etre',588],
                    [10,5,'etre',743],
                            [11,5,'dsfe',743]
                           ]),
                  columns=['id','group_col','label1','label2']
                  )

def GroupComparison(df, ID,group_col, label1, label2 ):
    oppdatert=[]
    for group in df.group_col.drop_duplicates():
        g = df.loc[df.group_col == group]
        if g.label2.nunique()<g.id.count():
            npers = g.id.count()
            g = g.reset_index().drop('index', axis=1)
            var1 = g.iloc[[0]]['label1']
            var2 = g.iloc[[0]]['label2']
            g['label1']= var1
            g['label2']= var2
            g=g.fillna(method = 'ffill')
            oppdatert.append(g)
    opp = pd.concat(oppdatert)
    return opp

test = GroupComparison(df, 'id', 'group_col', 'label1', 'label2' )
test.head(11)
于 2020-03-30T16:23:00.093 回答
0

该示例为第 1 组添加了一条额外的记录“label2”,该记录中断了序列,以说明数据未排序的可能性。通过 label2 值。

输入.csv

1,1,abcd,123
1,1,asdf,13
2,1,nfrv,123
3,2,dfgd,
4,3,kgff,899
5,3,kgff,899
6,3,ygoi,899
7,4,tgfo,
8,4,tgfo,
#!/usr/bin/env python

import pandas as pd

if __name__ == "__main__":
    d = pd.read_csv("input.csv")
    d["label1_new"] = d["label1"]

    print("```")
    print(d)
    print("```")

    # grouping by group_col and label2 will identify groups to be assigned label1_new values.
    g = d.groupby(by=["group_col", "label2"])
    for key, df_grp in g:
        label1_new = df_grp.iloc[0,2]

        #I didn't understand how to use the Pandas group to update in place.
        #Therefore I made a copy to hold new label1_new values.
        #Then updated the original data frame.
        cp = df_grp.copy()
        cp["label1_new"] = label1_new
        d.update(cp)

    print("```")
    print(d)
    print("```")

添加了 label1_new 的输入数据框

第一步是使用原始 lable1 的默认值添加列 label1_new。这可以处理所有没有 size > 1 的 label2 组的情况。

   id  group_col label1  label2 label1_new
0   1          1   abcd   123.0       abcd
1   1          1   asdf    13.0       asdf
2   2          1   nfrv   123.0       nfrv
3   3          2   dfgd     NaN       dfgd
4   4          3   kgff   899.0       kgff
5   5          3   kgff   899.0       kgff
6   6          3   ygoi   899.0       ygoi
7   7          4   tgfo     NaN       tgfo
8   8          4   tgfo     NaN       tgfo

更新的数据框

    id  group_col label1  label2 label1_new
0  1.0        1.0   abcd   123.0       abcd
1  1.0        1.0   asdf    13.0       asdf
2  2.0        1.0   nfrv   123.0       abcd
3  3.0        2.0   dfgd     NaN       dfgd
4  4.0        3.0   kgff   899.0       kgff
5  5.0        3.0   kgff   899.0       kgff
6  6.0        3.0   ygoi   899.0       kgff
7  7.0        4.0   tgfo     NaN       tgfo
8  8.0        4.0   tgfo     NaN       tgfo
于 2020-03-30T17:41:05.067 回答