我如何比较 DataFrame 中的所有列,根据任意比较函数(其中比较函数是可传递的)删除“小于”其他列的列。
例如如果我有 DataFrame
0 1 2 3 4 5
0 4 1 1 3 6 2
1 4 2 2 7 2 6
2 4 3 3 3 6 2
3 4 8 3 7 2 6
我的函数是“如果所有行 i 的 A[i] < B[i],则 A 列 < B 列”,结果将是
0 1 3 4
0 4 1 3 6
1 4 2 7 2
2 4 3 3 6
3 4 8 7 2
将第 2 列删除为 (4>1, 4>2, 4>3, 4>3),将第 5 列删除为 (3>2, 7>6, 3>2, 7>6)。
我最初/明显但缓慢的方法是,这可以在 n^2 时间内完成(伪代码;我之前没有做过太多 Pandas 编程......将不胜感激使用真实代码的答案)
for i in range(0, n):
for j in range(0, n):
if my_less_than_function(col(i), col(j)):
# i < j
drop col(i)
如果 less than 函数是可传递的,我还可以记住我已经删除了哪些列,并在迭代 i 和 j 时跳过它们。如果我的比较函数返回 (-1, 0, 1) for (less, equal, more) 而不是 (true, false) for (less, equal or more),我也可以在 range(i + 1, n) 中迭代 j
请注意,比较函数可能不是按行成对的,例如它可以是 sum(col A) < sum(col B) 或 number_of_primes_in(col A) < number_of_primes_in(col B)
谢谢
最佳答案
设置
df = pd.DataFrame([
[4, 1, 1, 3, 6, 2],
[4, 2, 2, 7, 2, 6],
[4, 3, 3, 3, 6, 2],
[4, 8, 3, 7, 2, 6]
], columns=list('abcdef'))
print(df)
a b c d e f
0 4 1 1 3 6 2
1 4 2 2 7 2 6
2 4 3 3 3 6 2
3 4 8 3 7 2 6
numpy
广播
对于 less_than
的定义我们可以使用 numpy
v = df.values
lt = pd.DataFrame((v.T[:, None] < v.T).all(-1), df.columns, df.columns)
print(lt)
a b c d e f
a False False False False False False
b False False False False False False
c True False False False False False
d False False False False False False
e False False False False False False
f False False False True False False
您可以通过以下方式拉出特定的列:
>= 'f'
的所有列
df.loc[:, lt.loc['f']]
d
0 3
1 7
2 3
3 7
< 'f'
的所有列
df.loc[:, ~lt.loc['f']]
a b c e f
0 4 1 1 6 2
1 4 2 2 2 6
2 4 3 3 6 2
3 4 8 3 2 6
关于python - Pandas 将所有 DataFrame 列相互比较,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41337316/