如果另一列满足条件,则当列值重复时删除一行

问题描述 投票:0回答:2

我有一个 DataFrame,我想在其中删除一行(或多行),其中超过一个连续的行根据不同列的值对一列具有相同的值。在这种情况下,如果高则保留 B 中值最高的行,如果低则保留值最低的行。本质上,我只是想先高后低,低点后高。

df = pd.DataFrame({'A': ['low', 'high', 'high', 'low', 'low','low'],                   
                   'B': [10, 70, 90, 40, 50,60]}) 

输出:

     A     B
0   low   10
1   high  70
2   high  90
3   low   40
4   low   50
5   low   60

期望:

     A     B
0   low   10
2   high  90
3   low   40

试图让我的头脑围绕如何实现逻辑并遇到了砖墙。

python python-3.x pandas dataframe pandas-groupby
2个回答
0
投票

这是另一种方式:

d = {'low':-1}

(df.assign(B = df['B'].mul(df['A'].map(d),fill_value=1))
 .groupby(['A',pd.Series(pd.factorize(df['A'])[0]).diff().ne(0).cumsum()]).max()
 .abs()
 .sort_index(level=1)
 .droplevel(1)
 .reset_index())

df.loc[df['A'].map({'low':-1}).mul(df['B'],fill_value=1).groupby(df['A'].ne(df['A'].shift()).cumsum()).idxmax()]

输出:

      A     B
0   low  10.0
1  high  90.0
2   low  40.0

0
投票

这是使用

groupby.apply
的快速而肮脏的方法:

out = (df.groupby(['A', df['A'].ne(df['A'].shift()).cumsum()])
       .apply(lambda x: x.max() if x['A'].iat[0]=='high' else x.min())
       .droplevel(0).sort_index().reset_index(drop=True))

另一种方法可能是先找到

groupby
+
max
;然后
mask
“低”值并将它们替换为
groupby
+
min
值:

g = df.groupby(['A', df['A'].ne(df['A'].shift()).cumsum()], sort=False)['B']
out = g.max().mask(lambda x: x.index.get_level_values(0)=='low', g.min()).droplevel(1).reset_index()

输出:

      A   B
0   low  10
1  high  90
2   low  40
© www.soinside.com 2019 - 2024. All rights reserved.