提问人:Alex Bejan 提问时间:11/11/2021 最后编辑:Alex Bejan 更新时间:11/11/2021 访问量:168
在数据帧中查找重复项并仅保留最高的重复项
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
速度也很重要,不能向前看。
答:
1赞
Rodalm
11/11/2021
#1
使用 + 屏蔽每个组的最小值。然后使用蒙版仅选择所需的行。groupby
transform
# 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
评论
0赞
Alex Bejan
11/11/2021
问题是你可以有多个组,所以这会把它们全部分组,我需要的是每个组集中的最小值。我已经更新了数据帧
0赞
Joshua Voskamp
11/11/2021
@AlexBejan你说的“群体”是什么意思?
1赞
Rodalm
11/11/2021
@AlexBejan我已经更新了答案。这是你要找的吗?
1赞
Rodalm
11/11/2021
@JoshuaVoskamp我知道这一点,但老实说,我更喜欢这种方式,我认为它更具可读性!但这只是一个偏好问题
1赞
Alex Bejan
11/11/2021
太好了,工作起来很有魅力,谢谢先生!
1赞
Joshua Voskamp
11/11/2021
#2
@HarryPlotter 的回答的单行版本:
df.loc[df.value.ne(df.groupby(df.group.ne(df.group.shift()).cumsum()).value.transform('min'))]
使用这里的技巧来应用OP对“分组”的理解,并进行转换以获得每个组中的最小值,然后对所有不等于这些值的值进行-ing。.loc
警告:这会删除任何单例“组”!(如果 OP 的注释表明“保持除最低值之外的所有值”,则丢弃了从技术上讲也是其组中“最高”的单例值。
1赞
Алексей Р
11/11/2021
#3
使用 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
评论
0赞
Alex Bejan
11/11/2021
似乎不起作用,它仍然具有组中的所有值
0赞
Алексей Р
11/11/2021
这很奇怪。它对我有用,请参阅上面的完整示例和结果。以防万一,替换为.ne(1)
.gt(1)
0赞
Alex Bejan
11/11/2021
仍然不适用于我的数据,不知道为什么。我已经接受了@HarryPlotter的解决方案,这很好,无论如何,谢谢
0赞
Алексей Р
11/11/2021
与预期结果不同的原因是,在更新描述后,我没有阅读有关顺序组的说明。代码已更新。
0赞
Alex Bejan
11/11/2021
是的,它现在正在工作,谢谢!
评论