如果另一列满足条件,则在列值重复时删除一行
Drop a row when a column value is duplicated if another column meets a criteria
我有一个 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
试图了解如何实现逻辑并将 运行 变成一堵砖墙。
这是使用 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
这是另一种方式:
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())
输出:
A B
0 low 10.0
1 high 90.0
2 low 40.0
我有一个 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
试图了解如何实现逻辑并将 运行 变成一堵砖墙。
这是使用 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
这是另一种方式:
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())
输出:
A B
0 low 10.0
1 high 90.0
2 low 40.0