如何将数据框中的所有列进行比较,根据任意比较函数(其中比较函数是传递功能)。删除小于其他列的列。<<<<<<<<<<<</p>
例如。如果我有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
,我的功能是"列a&lt;列B,如果a [i]&lt; b [i]对于所有行i",结果将为
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列AS(3> 2,7> 6,3> 2,7> 6)。
我的初始/明显但慢的方法是,这可以在N^2的情况下使用(伪代码;我在pandas编程之前都没有做太多的pandas编程。P>
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)
如果较小的功能是及传递的,我也可以记住我已经丢弃了哪些列并在迭代i和j时跳过它们。如果我的比较函数返回(-1,0,1),我也可以在范围(i 1,n)中迭代J,而不是(较小,相等,更多),而不是(较小,相等或更多)
请注意,比较函数可能不会通过行分为成对。可能是总和(col a)&lt;sum(col b)或number_of_primes_in(col A)&lt;number_of_primes_in(col B)
谢谢
setup
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
尝试以下:
In [278]: df
Out[278]:
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
In [279]: cols2drop = [col for col in df.columns if df.T.gt(df[col]).all(1).any()]
In [280]: cols2drop
Out[280]: [2, 5]
In [282]: df = df.drop(cols2drop, 1)
In [283]: df
Out[283]:
0 1 3 4
0 4 1 3 6
1 4 2 7 2
2 4 3 3 6
3 4 8 7 2
说明:
In [286]: df.T.gt(df[2])
Out[286]:
0 1 2 3
0 True True True True
1 False False False True
2 False False False False
3 True True False True
4 True False True False
5 True True False True
In [287]: df.T.gt(df[2]).all(1)
Out[287]:
0 True
1 False
2 False
3 False
4 False
5 False
dtype: bool
In [288]: df.T.gt(df[2]).all(1).any()
Out[288]: True