我的pandas数据框df
看起来像这样(输入):
Item Color
Car 1
Car 2
Bike 3
Bike 1
Train 4
Train 1
我想找到每Color
个值{输出>通常至少出现一次的Item
值:
Item Color
Car 1
Bike 1
Train 1
我目前的做法是基于一个循环而且无可否认是丑陋的。我相信有更多的pythonic /有效方式,理想情况下是单线。
all_colors = df.Color.unique().tolist()
for single_color in all_colors:
df_slice = df[df.Color = single_color]
if len(df_slice) = len(df.Item.unique().tolist()):
print "Shared Color", single_color
print df_slice
else:
continue
如何查找之前由该列定义的每个子集中存在的pandas单元格值?
编辑:问题标题也很笨重 - 如果有人有更好的措辞,请随意
答案 0 :(得分:3)
选项1
使用groupby
+ value_counts
+ unstack
,然后进行非空检查。
v = df.groupby('Item').Color.value_counts().unstack().notnull().all(0)
df[df.Color.isin(v.index[v])]
Item Color
0 Car 1
3 Bike 1
5 Train 1
详细
groupby
后跟unstack
的结果如下所示:
df.groupby('Item').Color.value_counts().unstack()
Color 1 2 3 4
Item
Bike 1.0 NaN 1.0 NaN
Car 1.0 1.0 NaN NaN
Train 1.0 NaN NaN 1.0
现在,只需使用行notnull
+ all
找到没有任何NaN的列。然后,使用它来索引df
。
选项2
get_dummies
+ sum
-
v = pd.get_dummies(df.set_index('Item').Color).sum(0).eq(df.Item.nunique())
df[df.Color.isin(v.index[v])]
Item Color
0 Car 1
3 Bike 1
5 Train 1
详细
在这里,我利用get_dummies
找出了#df.Item.nunique()
次代表的颜色。
pd.get_dummies(df.set_index('Item').Color).sum(0)
1 3
2 1
3 1
4 1
dtype: int64
df.Item.nunique()
3
选项3
与前两个类似,但这会使用pd.crosstab
,然后您只需检查所有行的计数是否大于或等于1
:
v = pd.crosstab(df.Item, df.Color).ge(1).all(0)
df[df.Color.isin(v.index[v])]
Item Color
0 Car 1
3 Bike 1
5 Train 1
答案 1 :(得分:2)
您需要duplicated
df[df.duplicated('Color',keep=False)]
Out[1148]:
Item Color
0 Car 1
3 Bike 1
5 Train 1
感谢冷点吧
v=(df.groupby('Color').agg(lambda x : len(list(x)))==df.Item.nunique())
v.index[v.Item]
Out[1174]: Int64Index([1], dtype='int64', name='Color')
df.loc[df.Color.isin(v.index[v.Item]),:]
Out[1175]:
Item Color
0 Car 1
3 Bike 1
5 Train 1
答案 2 :(得分:1)
找出我们唯一的项目数等于3的颜色。用isin
作为布尔索引过滤掉。
num_unique = df.groupby("Color")["Item"].nunique().reset_index()
df[df.Color.isin(num_unique[num_unique.Item == 3].Color)]
Item Color
0 Car 1
3 Bike 1
5 Train 1