如何找到之前由列定义的每个子集中存在的pandas单元格值?

时间:2018-01-23 04:30:27

标签: python pandas

我的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单元格值?

编辑:问题标题也很笨重 - 如果有人有更好的措辞,请随意

3 个答案:

答案 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