这是我的数据框:
df= pd.DataFrame(
{"mat" : ['A' ,'A', 'A', 'A', 'B'],
"ppl" : ['P', 'P', 'P', '', 'P'],
"ia1" : ['', 'X', 'X', '', 'X'],
"ia2" : ['X', '', '', 'X', 'X']},
index = [1, 2, 3, 4, 5])
我想在两个第一列上选择唯一值。我这样做:
df2 = df.loc[:,['mat','ppl']].drop_duplicates(subset=['mat','ppl']).sort_values(by=['mat','ppl'])
我得到了,正如所料:
mat ppl
4 A
1 A P
5 B P
我现在想要的是,df3是:
mat ppl ia1 ia2
A X
A P X X
B P X X
那就是:在df3
对于行A + P,在列ia1中,我得到了一个X,因为在df
的行之一的列ia1中有一个X,对于A + P
答案 0 :(得分:1)
使用aggregate
和unique
的解决方案,如果有多个唯一值与,
结合使用:
df = df.groupby(['mat','ppl']).agg(lambda x: ','.join(x[x != ''].unique())).reset_index()
print (df)
mat ppl ia1 ia2
0 A X
1 A P X X
2 B P X X
说明:
聚合正在使用Series
和聚合函数,其中输出是标量。我使用自定义函数,首先通过布尔索引(x[x != '']
过滤掉空格,然后获取唯一值。对于标量输出使用join
- 如果空系列(所有值都是空字符串)则有效;第二个优点是如果多个唯一值与,
得到一个连接值。
对于测试,可以使用与lambda函数相同的自定义函数:
def f(x):
a = ''.join(x[x != ''].unique().tolist())
return a
df = df.groupby(['mat','ppl']).agg(f).reset_index()
print (df)
mat ppl ia1 ia2
0 A X
1 A P X X
2 B P X X
正如OP的评论所述:
而不是使用lambda x:','。join(x [x!=''] .unique()),我使用了lambda x:','。join(set(x)-set(['' ]))。 我从13分5秒到43.2秒