gpt4 book ai didi

pandas - 从 Pandas 数据框中删除 'dominated' 行(所有值都低于任何其他行的值的行)

转载 作者:行者123 更新时间:2023-12-02 18:37:44 25 4
gpt4 key购买 nike

编辑:为了清晰起见,更改了示例 df

我有一个数据框,类似于下面给出的数据框(除了真实的数据框有几千行和几千列,并且值是 float ):

df = pd.DataFrame([[6,5,4,3,8], [6,5,4,3,6], [1,1,3,9,5], [0,1,2,7,4], [2, 0, 0, 4, 0])

0 1 2 3 4
0 6 5 4 3 8
1 6 5 4 3 6
2 1 1 3 9 5
3 0 1 2 7 4
4 2 0 0 4 0

从此数据框中,我想删除所有值都低于或等于任何其他行的所有行。对于这个简单的示例,应删除第 1 行和第 3 行(分别由第 0 行和第 2 行“主导”):

filtered df:
0 1 2 3 4
0 6 5 4 3 8
2 1 1 3 9 5
4 2 0 0 4 0

如果该方法可以考虑浮点错误,那就更好了,因为我的真实数据帧包含 float (即,不要删除所有值都较低/相等的行,这些值不应低于一个小量(例如 0.0001)。

我解决这个问题的最初想法如下:

  1. 选择第一行
  2. 使用列表理解将其他行与其进行比较(见下文)
  3. 删除所有返回 True 的行
  4. 对下一行重复此操作

列表理解代码:

selected_row = df.loc[0
[(df.loc[r]<=selected_row).all() and (df.loc[r]<selected_row).any() for r in range(len(df))]
[False, True, False, False, False]

但这似乎效率不高。任何有关如何(有效)解决此问题的建议将不胜感激。

最佳答案

我们可以尝试使用 broadcasting :

import pandas as pd

df = pd.DataFrame([
[6, 5, 4, 3, 8], [6, 5, 4, 3, 6], [1, 1, 3, 9, 5],
[0, 1, 2, 7, 4], [2, 0, 0, 4, 0]
])

# Need to ensure only one of each row present since comparing to 1
# there needs to be one and only one of each row
df = df.drop_duplicates()

# Broadcasted comparison explanation below
cmp = (df.values[:, None] <= df.values).all(axis=2).sum(axis=1) == 1

# Filter using the results from the comparison
df = df[cmp]

df:

   0  1  2  3  4
0 6 5 4 3 8
2 1 1 3 9 5
4 2 0 0 4 0

直觉:

通过 DataFrame 广播比较操作:

(df.values[:, None] <= df.values)
[[[ True  True  True  True  True]
[ True True True True False]
[False False False True False]
[False False False True False]
[False False False True False]] # df vs [6 5 4 3 8]

[[ True True True True True]
[ True True True True True]
[False False False True False]
[False False False True False]
[False False False True False]] # df vs [6 5 4 3 6]

[[ True True True False True]
[ True True True False True]
[ True True True True True]
[False True False False False]
[ True False False False False]] # df vs [1 1 3 9 5]

[[ True True True False True]
[ True True True False True]
[ True True True True True]
[ True True True True True]
[ True False False False False]] # df vs [0 1 2 7 4]

[[ True True True False True]
[ True True True False True]
[False True True True True]
[False True True True True]
[ True True True True True]]] # df vs [2 0 0 4 0]

然后我们可以检查allaxis=2上:

(df.values[:, None] <= df.values).all(axis=2)
[[ True False False False False]   # Rows le [6 5 4 3 8]
[ True True False False False] # Rows le [6 5 4 3 6]
[False False True False False] # Rows le [1 1 3 9 5]
[False False True True False] # Rows le [0 1 2 7 4]
[False False False False True]] # Rows le [2 0 0 4 0]

然后我们可以使用sum总计有多少行小于或等于:

(df.values[:, None] <= df.values).all(axis=2).sum(axis=1)
[1 2 1 2 1]

只有 1 行小于或等于(仅自匹配)的行是要保留的行。因为我们drop_duplicates数据框中不会有重复项,因此唯一的 True 值将是自匹配值以及小于或等于的值:

(df.values[:, None] <= df.values).all(axis=2).sum(axis=1) == 1
[ True False  True False  True]

这将成为 DataFrame 的过滤器:

df = df[[True, False, True, False, True]]

df:

   0  1  2  3  4
0 6 5 4 3 8
2 1 1 3 9 5
4 2 0 0 4 0

关于pandas - 从 Pandas 数据框中删除 'dominated' 行(所有值都低于任何其他行的值的行),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/68522283/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com