我有一个数据框:
id to from flag
1 a x 1
1 a y 0
2 c z 1
2 c m 1
2 b v 0
2 b p 0
,并且我想groupby(['id','to'])并返回其中仅带有标志1的元素的列表。如果没有元素具有标志1,则结果输出应为“无”。所需的输出应为:
id to from
1 a ['x']
2 c ['z','m']
2 b None
我可以申请
out_df = df.groupby(['id', 'to'])['from'].apply(
lambda x: match_to_list(x['from'], x['flag'])).reset_index()
其中:
def match_to_list(to, flag):
matches = list(to.iloc[flag.nonzero()[0]])
if len(matches) == 0:
return 'None'
else:
matches
但是这花费了太长时间,我认为必须有一种更好的方法来弥补我的缺失。
任何帮助/见解将不胜感激! TIA
答案 0 :(得分:0)
IIUC 1st用MultiIndex
创建索引,然后我们用groupby
进行agg
idx=pd.MultiIndex.from_tuples(list(map(tuple,df[['id','to']].drop_duplicates().values.tolist())))
yourdf=df.loc[df.flag==1].groupby(['id','to'])['from'].agg(list).reindex(idx).reset_index()
yourdf
Out[13]:
level_0 level_1 from
0 1 a [x]
1 2 c [z, m]
2 2 b NaN
或者仅使用apply,效率较低但可读性更高
df.groupby(['id','to']).apply(lambda x : x['from'][x['flag']==1].tolist() if (x['flag']==1).any() else None).reset_index()
Out[17]:
id to 0
0 1 a [x]
1 2 b None
2 2 c [z, m]