我有一个由ID索引的python数据框,其中每个ID出现多次。我想按ID对数据进行分组,检查每个ID是否有多个" source",然后过滤我的原始数据,只包含ID只有一个来源的行。
我想我可以这样做,第一行获取要过滤的ID列表,第二行执行过滤:
df_onesourceids=df.reset_index().groupby('ID').apply(lambda d: d.my_source.nunique()).where(lambda x : x==1).dropna()
df=df.loc[df_onesourceids.index.tolist()]
这是交互式工作,但当我在我们的构建系统中运行时,我得到一个错误(在第二行,第一行很好,并产生一个系列,其中索引是ID,值为1.0)来自pytest( /lib/python2.7/site-packages/_pytest/_code/code.py
):
ValueError:具有多个元素的数组的真值是不明确的。使用a.any()
或a.all()
我尝试了很多变通办法,包括isin函数或将我的列表转换为数据框。我一直收到这个错误。我怎么能这样做?
答案 0 :(得分:1)
我认为您需要transform
nunique
并按boolean indexing
过滤:
df = df[df.groupby(level='ID')['my_source'].transform('nunique') == 1]
使用filtration的更慢的解决方案:
df = df.groupby(level='ID').filter(lambda d: d.my_source.nunique() == 1)
样品:
df = pd.DataFrame({'my_source':list('abcccc'),
'B':[4,5,4,0,0,0],
'C':[7,8,9,4,2,3],
'D':[1,3,5,7,1,0],
'E':[5,3,6,9,2,4]}, index=list('aaabbb'))
df.index.name = 'ID'
print (df)
B C D E my_source
ID
a 4 7 1 5 a
a 5 8 3 3 b
a 4 9 5 6 c
b 0 4 7 9 c
b 0 2 1 2 c
b 0 3 0 4 c
df1 = df.groupby(level='ID').filter(lambda d: d.my_source.nunique() == 1)
df1 = df[df.groupby(level='ID')['my_source'].transform('nunique') == 1]
print (df1)
B C D E my_source
ID
b 0 4 7 9 c
b 0 2 1 2 c
b 0 3 0 4 c
编辑:
df = df.reset_index()
df = df[df.groupby('ID')['my_source'].transform('nunique') == 1]