2016-12-13 104 views
0

我在熊貓中有一個平方相關矩陣,並且我試圖通過最有效的方式來返回所有值,其中值(總是浮點數-1 < = x < = 1)高於一定的閾值。熊貓 - 在所有列上過濾

pandas.DataFrame.filter方法要求列或RegEx的列表,但我總是想要通過所有列。是否有最佳做法呢?

+5

你可以添加樣品與期望的輸出?如果超出條件的值被「NaN」取代? – jezrael

回答

5

由於您沒有提供樣品,因此不確定您希望的輸出是什麼,但是我會給你我的兩分錢:

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 
+1

我提高了,因爲這教會了我一個處理對稱矩陣情況的好方法。 –

7

有兩種方法去了解這一點:

假設:

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 

如果你只想要的值,那麼最簡單的方法是使用values屬性與底層numpy數據結構一起工作:

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.  ]) 

相反的.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

除'values'之外,'stack()'也很有用,因爲它會自動刪除NaN,但會保留標籤。 – ayhan

+0

@ayhan好電話 –

+0

你的解決方案絕對比我的感覺更自然,但我會提醒的是,它確實保留了不必要的項目('('x','x')'必須始終爲1)以及排列組合: '('a','b')'與'('b','a')'相同。 (這很好,因爲我們仍然不知道OP的要求,所以我高舉了它) –