在数据框中查找重复项并仅保留最高的
Find duplicates in dataframe and keep only the highest ones
我试图在数据框中为每个组找到更高的重复项,这样我可以稍后根据索引从另一个数据框中删除这些重复项,这样主数据框就没有重复项,只有最低值。
基本上假设我们有这个数据框:
index group value
1 1 402
2 1 396
3 2 406
4 2 416
5 2 407
6 2 406
7 1 200
8 2 350
我需要的是仅保留每组连续重复项中具有最高值的重复项并删除最低值。该组为 1 或 2,但同一组中可以有多个连续值实例。
因此生成的数据框将是:
index group value
1 1 402
4 2 416
5 2 407
速度也很重要,不能超前。
使用groupby
+ transform
屏蔽每组的最小值。然后使用掩码 select 仅需要的行。
# map each consecutive group of rows to a different integer
group_labels = (df.group != df.group.shift()).cumsum()
# find the minimum value of each group
group_min_val = df.groupby(group_labels)['value'].transform('min')
# get only the rows of each group whose value is higher than the minimum
res = df[df.value != group_min_val]
>>> res
index group value
0 1 1 402
3 4 2 416
4 5 2 407
中间结果
>>> group_labels
0 1
1 1
2 2
3 2
4 2
5 2
6 3
7 4
Name: group, dtype: int64
>>> group_min_val
0 396
1 396
2 406
3 406
4 406
5 406
6 200
7 350
Name: value, dtype: int64
>>> df.value != group_min_val
0 True
1 False
2 False
3 True
4 True
5 False
6 False
7 False
Name: value, dtype: bool
@HarryPlotter 的答案的单行版本:
df.loc[df.value.ne(df.groupby(df.group.ne(df.group.shift()).cumsum()).value.transform('min'))]
利用中的技巧应用OP对“分组”的理解,并进行转换以获得每个组中的最小值,然后.loc
-ing所有值不等于那些。
警告:这丢弃任何单例“组”! (OP 的评论表明“保留最低的”,这会丢弃从技术上讲也是他们组中的 'highest' 的单例值。)
使用 rank() 可以使这更容易。
在这种情况下,您需要决定如何处理相同的最小值 - 删除其中一个 (method = 'first'
) 或两个 (method = 'min'
)。基于解集method = 'first'
:
中的条件“去掉最低的”
df = pd.DataFrame({'index': [1, 2, 3, 4, 5, 6, 7], 'group': [1, 1, 2, 2, 2, 1, 2],
'value': [402, 396, 406, 416, 407, 200, 350]}).set_index('index')
print('Source df:\n', df)
df = df[df.groupby(df.group.diff().ne(0).cumsum())['value'].rank(method='first').gt(1)]
print('\nResult df:\n', df)
输出:
Source df:
group value
index
1 1 402
2 1 396
3 2 406
4 2 416
5 2 407
6 1 200
7 2 350
Result df:
group value
index
1 1 402
4 2 416
5 2 407
我试图在数据框中为每个组找到更高的重复项,这样我可以稍后根据索引从另一个数据框中删除这些重复项,这样主数据框就没有重复项,只有最低值。
基本上假设我们有这个数据框:
index group value
1 1 402
2 1 396
3 2 406
4 2 416
5 2 407
6 2 406
7 1 200
8 2 350
我需要的是仅保留每组连续重复项中具有最高值的重复项并删除最低值。该组为 1 或 2,但同一组中可以有多个连续值实例。 因此生成的数据框将是:
index group value
1 1 402
4 2 416
5 2 407
速度也很重要,不能超前。
使用groupby
+ transform
屏蔽每组的最小值。然后使用掩码 select 仅需要的行。
# map each consecutive group of rows to a different integer
group_labels = (df.group != df.group.shift()).cumsum()
# find the minimum value of each group
group_min_val = df.groupby(group_labels)['value'].transform('min')
# get only the rows of each group whose value is higher than the minimum
res = df[df.value != group_min_val]
>>> res
index group value
0 1 1 402
3 4 2 416
4 5 2 407
中间结果
>>> group_labels
0 1
1 1
2 2
3 2
4 2
5 2
6 3
7 4
Name: group, dtype: int64
>>> group_min_val
0 396
1 396
2 406
3 406
4 406
5 406
6 200
7 350
Name: value, dtype: int64
>>> df.value != group_min_val
0 True
1 False
2 False
3 True
4 True
5 False
6 False
7 False
Name: value, dtype: bool
@HarryPlotter 的答案的单行版本:
df.loc[df.value.ne(df.groupby(df.group.ne(df.group.shift()).cumsum()).value.transform('min'))]
利用.loc
-ing所有值不等于那些。
警告:这丢弃任何单例“组”! (OP 的评论表明“保留最低的”,这会丢弃从技术上讲也是他们组中的 'highest' 的单例值。)
使用 rank() 可以使这更容易。
在这种情况下,您需要决定如何处理相同的最小值 - 删除其中一个 (method = 'first'
) 或两个 (method = 'min'
)。基于解集method = 'first'
:
df = pd.DataFrame({'index': [1, 2, 3, 4, 5, 6, 7], 'group': [1, 1, 2, 2, 2, 1, 2],
'value': [402, 396, 406, 416, 407, 200, 350]}).set_index('index')
print('Source df:\n', df)
df = df[df.groupby(df.group.diff().ne(0).cumsum())['value'].rank(method='first').gt(1)]
print('\nResult df:\n', df)
输出:
Source df:
group value
index
1 1 402
2 1 396
3 2 406
4 2 416
5 2 407
6 1 200
7 2 350
Result df:
group value
index
1 1 402
4 2 416
5 2 407