Pandas 如何在熊猫组中选择过滤元件

Pandas 如何在熊猫组中选择过滤元件,pandas,Pandas,我想根据熊猫组中的元素的属性有选择地删除它们 下面是一个示例:删除除“A”列中具有最高值的行之外的所有元素 >>> dff = pd.DataFrame({'A': np.arange(8), 'B': list('aabbbbcc'), 'C': list('lmnopqrt')}) >>> dff A B C 0 0 a l 1 2 a m 2 4 b n 3 1 b o 4 9 b p 5 2 b

我想根据熊猫组中的元素的属性有选择地删除它们

下面是一个示例:删除除“A”列中具有最高值的行之外的所有元素

>>> dff = pd.DataFrame({'A': np.arange(8), 'B': list('aabbbbcc'), 'C': list('lmnopqrt')})

>>> dff
   A  B  C
0   0  a  l
1   2  a  m
2   4  b  n
3   1  b  o
4   9  b  p
5   2  b  q
6   3  c  r
7  10  c  t

>>> grped = dff.groupby('B')
>>> grped.groups
{'a': [0, 1], 'c': [6, 7], 'b': [2, 3, 4, 5]}
将自定义函数/方法应用于组(在“A”列过滤元素的组内排序)

返回数据帧:

   A  B  C
0   2  a  m
1   9  b  p
2  10  c  t

也许有一种简洁的方法可以通过lambda函数或.filter()实现这一点?谢谢

如果要为每组选择一行,可以使用
groupby/agg
返回索引值并使用
loc
选择行

例如,要按
B
分组,然后选择
A
值最高的行:

In [171]: dff
Out[171]: 
    A  B  C
0   0  a  l
1   2  a  m
2   4  b  n
3   1  b  o
4   9  b  p
5   2  b  q
6   3  c  r
7  10  c  t

[8 rows x 3 columns]

In [172]: dff.loc[dff.groupby('B')['A'].idxmax()]
Out[172]: 
    A  B  C
1   2  a  m
4   9  b  p
7  10  c  t
另一个选项()实际上是

如果希望为每个组选择多行,可以使用
groupby/apply
,并使用一个函数为每个组返回子数据帧 每组<代码>应用然后将尝试为您合并这些子数据帧

例如,要从每个组中选择除最后一行之外的每一行,请执行以下操作:

In [216]: df = pd.DataFrame(np.arange(15).reshape(5,3), columns=list('ABC'), index=list('vwxyz')); df['A'] %= 2; df
Out[216]: 
   A   B   C
v  0   1   2
w  1   4   5
x  0   7   8
y  1  10  11
z  0  13  14


In [217]: df.groupby(['A']).apply(lambda grp: grp.iloc[:-1]).reset_index(drop=True, level=0)
Out[217]: 
   A  B  C
v  0  1  2
x  0  7  8
w  1  4  5
另一种方法是使用
groupby/apply
返回一系列索引值。再次
apply
将尝试将系列加入到一个系列中。然后可以使用
df.loc
按索引值选择行:

In [218]: df.loc[df.groupby(['A']).apply(lambda grp: pd.Series(grp.index[:-1]))]
Out[218]: 
   A  B  C
v  0  1  2
x  0  7  8
w  1  4  5

我不认为
groupby/filter
会做你想做的事,因为
groupby/filter
过滤整个组。它不允许您从每个组中选择特定的行。

@DSM:Oops,您是对的。谢谢你的更正。谢谢你的回答。我使用“loc”方法选择每个组的最大行数,但是性能太慢了。你有什么建议吗?
In [216]: df = pd.DataFrame(np.arange(15).reshape(5,3), columns=list('ABC'), index=list('vwxyz')); df['A'] %= 2; df
Out[216]: 
   A   B   C
v  0   1   2
w  1   4   5
x  0   7   8
y  1  10  11
z  0  13  14


In [217]: df.groupby(['A']).apply(lambda grp: grp.iloc[:-1]).reset_index(drop=True, level=0)
Out[217]: 
   A  B  C
v  0  1  2
x  0  7  8
w  1  4  5
In [218]: df.loc[df.groupby(['A']).apply(lambda grp: pd.Series(grp.index[:-1]))]
Out[218]: 
   A  B  C
v  0  1  2
x  0  7  8
w  1  4  5