2014-09-04 59 views
6

我试图使用需要2个参数的公式使用rollapply。据我所知的唯一途径(除非你从头开始创建公式)计算肯德尔tau蛋白的相关性,与包括标准约束校正是:使用rolling_apply函数,需要在熊猫的2个参数

>>> import scipy 
>>> x = [5.05, 6.75, 3.21, 2.66] 
>>> y = [1.65, 26.5, -5.93, 7.96] 
>>> z = [1.65, 2.64, 2.64, 6.95] 
>>> print scipy.stats.stats.kendalltau(x, y)[0] 
0.333333333333 

我也有rollapply并采取两个参数意识到了这个问题,这里记载:

尽管如此,我仍在努力寻找一种方法来对滚动基础上的多列数据框进行kendalltau计算。

我的数据帧是这样

A = pd.DataFrame([[1, 5, 1], [2, 4, 1], [3, 3, 1], [4, 2, 1], [5, 1, 1]], 
       columns=['A', 'B', 'C'], index = [1, 2, 3, 4, 5]) 

试图创建一个函数,这是否

In [1]:function(A, 3) # A is df, 3 is the rolling window 
Out[2]: 
    A B C  AB  AC  BC 
1 1 5 2 NaN NaN NaN 
2 2 4 4 NaN NaN NaN 
3 3 3 1 -0.99 -0.33 0.33 
4 4 2 2 -0.99 -0.33 0.33 
5 5 1 4 -0.99 0.99 -0.99 

在一个非常初步的方法,我招待定义这样的功能的想法:

def tau1(x): 
    y = np.array(A['A']) # keep one column fix and run it in the other two 
    tau, p_value = sp.stats.kendalltau(x, y) 
    return tau 

A['AB'] = pd.rolling_apply(A['B'], 3, lambda x: tau1(x)) 

Off course它没有工作。我得到了:

ValueError: all keys need to be the same shape 

我明白不是一个小问题。我很欣赏任何输入。

回答

5

As of Pandas 0.14,rolling_apply只将NumPy数组传递给函数。可能的解决方法是将np.arange(len(A))作为第一个参数传递给rolling_apply,以便tau函数接收的索引您希望使用的行。然后在tau函数中,

B = A[[col1, col2]].iloc[idx] 

返回一个包含所有需要的行的DataFrame。


import numpy as np 
import pandas as pd 
import scipy.stats as stats 
import itertools as IT 

A = pd.DataFrame([[1, 5, 2], [2, 4, 4], [3, 3, 1], [4, 2, 2], [5, 1, 4]], 
       columns=['A', 'B', 'C'], index = [1, 2, 3, 4, 5]) 

for col1, col2 in IT.combinations(A.columns, 2): 
    def tau(idx): 
     B = A[[col1, col2]].iloc[idx] 
     return stats.kendalltau(B[col1], B[col2])[0] 
    A[col1+col2] = pd.rolling_apply(np.arange(len(A)), 3, tau) 

print(A)  

产生

A B C AB  AC  BC 
1 1 5 2 NaN  NaN  NaN 
2 2 4 4 NaN  NaN  NaN 
3 3 3 1 -1 -0.333333 0.333333 
4 4 2 2 -1 -0.333333 0.333333 
5 5 1 4 -1 1.000000 -1.000000 
+0

惊人。非常感谢!。我应该记住的列数是否有限制?这些itertools函数非常棒,并且超出了我的水平...以提出任何其他智能问题。 – hernanavella 2014-09-04 22:36:34

+0

组合的数量增长为'n ** 2',所以'tau'按'n = 2 * m'的次序调用,其中'm = len(A)'。所以这可能需要一段时间,特别是如果你有很多列。 [使用'itertools'](https://docs.python.org/2/library/itertools.html)真的很有趣;学习它并不难,而且值得花时间。 – unutbu 2014-09-05 00:43:18

+0

60K行x 4列〜7min – hernanavella 2014-09-05 16:02:24

相关问题