我试图从X列中删除连续的重复项,同时根据Y列保留最大值的条目,但遗憾的是没有成功。数据帧如下:
idx | X | Y | |
---|---|---|---|
0 | A | 3||
1 | B | 2[/tr>||
2 | A | 7 | |
3 | A | 10 | |
4 | B | <1>||
5 | C | 4 | |
6 | A | 3 | |
7 | A | 3 |
您需要应用itertools样式的groupby,然后保留Y最大的行。
>>> df
idx X Y
0 0 A 3
1 1 B 2
2 2 A 7
3 3 A 10
4 4 B 1
5 5 C 4
6 6 A 3
7 7 A 5
>>> y_max = df.groupby(df['X'].ne(df['X'].shift()).cumsum())['Y'].transform('max')
>>> df[df['Y'] == y_max]
idx X Y
0 0 A 3
1 1 B 2
3 3 A 10
4 4 B 1
5 5 C 4
7 7 A 5
编辑:
最初的解决方案有一个错误,只是偶然产生了正确的idx列。
编辑2:
如果你只想每组保留一行,你可以使用
>>> y_idxmax = df.groupby(df['X'].ne(df['X'].shift()).cumsum())['Y'].idxmax()
>>> df.loc[y_idxmax]
idx X Y
0 0 A 3
1 1 B 2
3 3 A 10
4 4 B 1
5 5 C 4
7 7 A 5
这一点要归功于Ch3steR。
或者我宁愿只在groupby
参数中指定组:
df.groupby(df['X'].ne(df['X'].shift()).cumsum(), as_index=False).max()
或者:
df.groupby(df['X'].ne(df['X'].shift()).cumsum()).max().reset_index(drop=True)
两种输出:
idx X Y
0 0 A 3
1 1 B 2
2 3 A 10
3 4 B 1
4 5 C 4
5 7 A 5
创建一列,将连续的数据堆到一个组中
df['temp']=(~(df['X']==df['X'].shift())|(df['X'].shift(-1)==df['X'])).cumsum()
一组接一组,并过滤掉其中Y的值等于每组中的最大值。放下温度柱
df[df.groupby('temp')['Y'].transform(lambda x:(x==x.max()))].drop(columns=['temp'])
更简洁的方法不是创建列,而是将连续的组保存到一个变量中,并按变量分组,如下所示
s=(~(df['X']==df['X'].shift())|(df['X'].shift(-1)==df['X'])).cumsum()
print(df[df.groupby(s)['Y'].transform(lambda x:(x==x.max()))])
idx X Y
0 0 A 3
1 1 B 2
3 3 A 10
4 4 B 1
5 5 C 4
7 7 A 5
我无法立即找出已经给出的答案,所以我写了一个简单的脚本来做同样的事情。它获取具有重复值的索引,并通过一次比较两个来删除它们。
检查以下代码-
import pandas as pd
data = {'X':['A', 'B', 'A', 'A', 'A', 'B', 'C', 'A', 'A'],
'Y': [3, 2, 12, 7, 10, 1, 4, 3, 5]}
data = pd.DataFrame(data)
mask = data['X'] == data['X'].shift()
to_check = data.loc[mask].index.tolist()
for i, _ in enumerate(to_check):
index = to_check[i]
if data.iloc[index]['Y'] > data.iloc[index - 1]['Y']:
data.drop(index - 1, axis=0, inplace=True)
data.reset_index(inplace=True, drop=True)
else:
data.drop(index, axis=0, inplace=True)
data.reset_index(inplace=True, drop=True)
to_check = [value - 1 for value in to_check]
print(data)
# OUTPUT
X Y
0 A 3
1 B 2
2 A 12
3 B 1
4 C 4
5 A 5