提问人:Thomas Murphy 提问时间:12/14/2016 最后编辑:Julien MarrecThomas Murphy 更新时间:2/26/2021 访问量:18121
Pandas - 跨所有列进行筛选
Pandas - Filter across all columns
问:
我在 pandas 中有一个平方相关矩阵,并试图以最有效的方式返回值(始终为浮点数 -1 <= x <= 1)高于某个阈值的所有值。
熊猫。DataFrame.filter 方法要求提供列列表或正则表达式,但我总是想传入所有列。这方面有最佳实践吗?
答:
13赞
juanpa.arrivillaga
12/14/2016
#1
有两种方法可以解决这个问题:
假设:
In [7]: c = np.array([-1,-2,-2,-3,-4,-6,-7,-8])
In [8]: a = np.array([1,2,3,4,6,7,8,9])
In [9]: b = np.array([2,4,6,8,10,12,13,15])
In [10]: c = np.array([-1,-2,-2,-3,-4,-6,-7,-8])
In [11]: corr = np.corrcoef([a,b,c])
In [12]: df = pd.DataFrame(corr)
In [13]: df
Out[13]:
0 1 2
0 1.000000 0.995350 -0.980521
1 0.995350 1.000000 -0.971724
2 -0.980521 -0.971724 1.000000
然后,您可以简单地:
In [14]: df > 0.5
Out[14]:
0 1 2
0 True True False
1 True True False
2 False False True
In [15]: df[df > 0.5]
Out[15]:
0 1 2
0 1.00000 0.99535 NaN
1 0.99535 1.00000 NaN
2 NaN NaN 1.0
如果只需要值,那么最简单的方法是使用以下属性处理底层 numpy 数据结构:values
In [17]: df.values
Out[17]:
array([[ 1. , 0.99535001, -0.9805214 ],
[ 0.99535001, 1. , -0.97172394],
[-0.9805214 , -0.97172394, 1. ]])
In [18]: df.values[(df > 0.5).values]
Out[18]: array([ 1. , 0.99535001, 0.99535001, 1. , 1. ])
而不是 ,正如 ayhan 所指出的那样,您可以使用它自动丢弃并保留标签.......values
stack
NaN
In [22]: df.index = ['a','b','c']
In [23]: df.columns=['a','b','c']
In [24]: df
Out[24]:
a b c
a 1.000000 0.995350 -0.980521
b 0.995350 1.000000 -0.971724
c -0.980521 -0.971724 1.000000
In [25]: df.stack() > 0.5
Out[25]:
a a True
b True
c False
b a True
b True
c False
c a False
b False
c True
dtype: bool
In [26]: df.stack()[df.stack() > 0.5]
Out[26]:
a a 1.00000
b 0.99535
b a 0.99535
b 1.00000
c c 1.00000
dtype: float64
你随时可以回去......
In [29]: (df.stack()[df.stack() > 0.5]).unstack()
Out[29]:
a b c
a 1.00000 0.99535 NaN
b 0.99535 1.00000 NaN
c NaN NaN 1.0
评论
2赞
ayhan
12/14/2016
除了 之外,它还很有用,因为它会自动删除 NaN,但会保留标签。values
stack()
0赞
Julien Marrec
12/14/2016
你的解决方案肯定比我的更自然,但我要注意的是,它确实维护了不必要的项目(那些必须总是 1)以及排列:与 相同。(这很好,因为我们仍然不知道 OP 的确切要求,所以我投了赞成票)('x','x')
('a','b')
('b','a')
0赞
Thomas Murphy
12/14/2016
@juanpa.arrivillaga 这也是一种强有力的看待它的方式!我认为 Julien 感觉更有说服力/Pythonic,但我也看到了这方面的用例。
16赞
Julien Marrec
12/14/2016
#2
不确定您想要的输出是什么,因为您没有提供样本,但我会给你两美分的我会做什么:
In[1]:
import pandas as pd
import numpy as np
df = pd.DataFrame(np.random.rand(10,5))
corr = df.corr()
corr.shape
Out[1]: (5, 5)
现在,让我们提取相关矩阵的上三角形(它是对称的),不包括对角线。为此,我们将使用 np.tril
,将其转换为布尔值,并使用运算符获得与之相反的值。~
In [2]: corr_triu = corr.where(~np.tril(np.ones(corr.shape)).astype(np.bool))
corr_triu
Out[2]:
0 1 2 3 4
0 NaN 0.228763 -0.276406 0.286771 -0.050825
1 NaN NaN -0.562459 -0.596057 0.540656
2 NaN NaN NaN 0.402752 0.042400
3 NaN NaN NaN NaN -0.642285
4 NaN NaN NaN NaN NaN
现在让我们堆叠它并过滤上面的所有值,例如:0.3
In [3]: corr_triu = corr_triu.stack()
corr_triu[corr_triu > 0.3]
Out[3]:
1 4 0.540656
2 3 0.402752
dtype: float64
如果你想让它更漂亮一点:
In [4]: corr_triu.name = 'Pearson Correlation Coefficient'
corr_triu.index.names = ['Col1', 'Col2']
In [5]: corr_triu[corr_triu > 0.3].to_frame()
Out[5]:
Pearson Correlation Coefficient
Col1 Col2
1 4 0.540656
2 3 0.402752
评论
2赞
juanpa.arrivillaga
12/14/2016
我投了赞成票,因为这教会了我一种处理对称矩阵情况的好方法。
1赞
msklc
12/27/2019
#3
为了从 pandas 数据帧中轻松获得有意义的关联结果;
例如,我们的数据:
df = pd.DataFrame(np.random.randn(10, 5),
columns=['a', 'b', 'c', 'd', 'e'])
df
我们得到值之间的相关性df.corr()
通过忽略 1.0(它们是相同值的相关性)来过滤结果并过滤限制;
corr_result=df.corr()
corr_result = corr_result.stack()
corr_result[(corr_result != 1.0)&((corr_result > 0.9)|(corr_result < -0.9))]
3赞
huang
2/26/2021
#4
放下 NaN 以便于阅读。
df[df > 100].dropna(axis=0, how='all').dropna(axis=1, how='all')
评论
NaN