我试图一次浏览我的数据框两行,检查两行中的列值是否相同并删除这些行。我的数据框跟踪不同人在不同遭遇中的位置。
我有一个名为 transfers
的数据框,其中每一行都包含一个人的 ID 号、一个遭遇号和一个位置。 transfers
数据框是通过在我的原始数据框上运行一个副本来创建的,以查找具有相同人员 ID 的行,并将它们分组在一起。
例如,我们想去掉下面数据框中 ID = 2
的行,因为两次遇到的位置都是 "D"
,所以这人没有动。
但是,我们希望保留 ID = 3
的行,因为该人从 “A”
移动到 “F”
。
另一个问题出现是因为有些人有超过两行,例如 ID = 1
。对于这个人,我们希望保留他们的行,因为他们已经从 "A"
-> "B"
移动,然后从 "B"
-> “C”
。不过,如果只比较遭遇12和13,这人似乎并没有改变位置。
示例数据框 df
:
ID Encounter Location
1 11 A
1 12 B
1 13 B
1 14 C
2 21 D
2 22 D
3 31 A
3 32 F
预期输出:
ID Encounter Location
1 11 A
1 12 B
1 13 B
1 14 C
3 31 A
3 32 F
我已经尝试使用 .iterrows()
进行嵌套的 for
循环,但我发现这不起作用,因为它非常慢并且没有正确处理以下情况这个人有过两次以上的遭遇。我也尝试过将一个函数应用于我的数据框,但运行时间几乎与粗循环相同。
编辑:我应该明确说明这一点,我试图保留任何移动位置的人的数据,即使他们最终回到了他们开始的地方。
最佳答案
给定
>>> df
ID Encounter Location
0 1 11 A
1 1 12 B
2 1 13 B
3 1 14 C
4 2 21 D
5 2 22 D
6 3 31 A
7 3 32 F
您可以通过
过滤您的数据框>>> places = df.groupby('ID')['Location'].transform('nunique')
>>> df[places > 1]
ID Encounter Location
0 1 11 A
1 1 12 B
2 1 13 B
3 1 14 C
6 3 31 A
7 3 32 F
我们的想法是计算每个组 (ID) 的唯一地点的数量,然后删除一个人只去过一个地方的行。
与 filter
解决方案的比较:
# setup
>>> df = pd.concat([df.assign(ID=df['ID'] + i) for i in range(1000)], ignore_index=True)
>>> df
ID Encounter Location
0 1 11 A
1 1 12 B
2 1 13 B
3 1 14 C
4 2 21 D
... ... ... ...
7995 1000 14 C
7996 1001 21 D
7997 1001 22 D
7998 1002 31 A
7999 1002 32 F
[8000 rows x 3 columns]
# timings @ i5-6200U CPU @ 2.30GHz
>>> %timeit df.groupby('ID').filter(lambda x: x['Location'].nunique() > 1)
356 ms ± 19.4 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)
>>> %timeit df[df.groupby('ID')['Location'].transform('nunique') > 1]
5.56 ms ± 21.5 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)
关于python - 删除人员未更改位置的行,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54055850/