我想这是相当简单的事情,但我找不到如何做到这一点。我一直在搜索教程和stackoverflow。
假设我有一个像这样的数据帧 df :
Group Id_In_Group SomeQuantity
1 1 10
1 2 20
2 1 7
3 1 16
3 2 22
3 3 5
3 4 12
3 5 28
4 1 1
4 2 18
4 3 14
4 4 7
5 1 36
我想只选择组中至少有 4 个对象的行(因此至少有 4 行具有相同的“组”编号),对于第 4 个对象的 SomeQuantity,当通过升序 SomeQuantity 在组中排序时,大于 20(例如)。
例如,在给定的 Dataframe 中,它只会返回第 3 个组,因为它有 4 个(>=4)成员,并且它的第 4 个 SomeQuantity(排序后)为 22(>=20),因此它应该构造 dataframe:
Group Id_In_Group SomeQuantity
3 1 16
3 2 22
3 3 5
3 4 12
3 5 28
(无论是否按 SomeQuantity 排序)。
有人可以帮助我吗? :)
最佳答案
使用 map
、 value_counts
、 groupby
、 filter
的方法略有不同:
(df[df.Group.map(df.Group.value_counts().ge(4))]
.groupby('Group')
.filter(lambda x: np.any(x['SomeQuantity'].sort_values().iloc[3] >= 20)))
步骤分解:
执行
value_counts
以计算 Group 列中存在的不同元素的总数。>>> df.Group.value_counts()
3 5
4 4
1 2
5 1
2 1
Name: Group, dtype: int64
使用功能类似于字典的
map
(其中索引成为键,系列元素成为值)将这些结果映射回原始 DF
>>> df.Group.map(df.Group.value_counts())
0 2
1 2
2 1
3 5
4 5
5 5
6 5
7 5
8 4
9 4
10 4
11 4
12 1
Name: Group, dtype: int64
然后,我们检查具有 4 或更多值的元素,这是我们的阈值限制,并仅从整个
DF
中获取那些子集。>>> df[df.Group.map(df.Group.value_counts().ge(4))]
Group Id_In_Group SomeQuantity
3 3 1 16
4 3 2 22
5 3 3 5
6 3 4 12
7 3 5 28
8 4 1 1
9 4 2 28
10 4 3 14
11 4 4 7
为了对此使用
groupby.filter
操作,我们必须确保在执行排序过程并将第四个元素与阈值 20 进行比较时,我们返回与每个分组键对应的单个 bool 值。np.any
返回与我们的过滤器匹配的所有此类可能性。>>> df[df.Group.map(df.Group.value_counts().ge(4))] \
.groupby('Group').apply(lambda x: x['SomeQuantity'].sort_values().iloc[3])
Group
3 22
4 18
dtype: int64
从这些中,我们比较第四个元素
.iloc[3]
因为它是基于 0 的索引并返回所有这些有利匹配。关于python - 根据行数对 Pandas Dataframe 进行切片,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/41505215/