我有一个难题。
我的数据有一个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 |
|----|----------|-------|------|------------|
另外请注意,这必须在数百万行/组上运行,因此应该尽可能高效
感谢您的帮助
事实上,我早些时候有点灵机一动,想出了一个可能的解决方案。还没有在大型数据喷射器上对其进行测试,也没有对其进行清理(稍后会进行清理(。但如果有人有更好的方法,我很乐意听到。
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)
该示例为组1添加了一个额外的记录,";标签2";这中断了序列以说明数据未被排序的可能性。通过标记2值。
input.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。这处理不存在大小>的标签2组的所有情况;1.
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