基于DataFrame将参数传递给stats.friedmanchisquare的正确方法是什么?

时间:2015-07-02 22:57:04

标签: python numpy pandas scipy

我正在尝试将值stats.friedmanchisquare传递给数据框df,其形状为(11,17)

这对我来说是工作(在这个例子中只有三行):

df = df.as_matrix()
print stats.friedmanchisquare(df[1, :], df[2, :], df[3, :])

产生

(16.714285714285694, 0.00023471398805908193)

但是,当我想使用11的所有df行时,代码行太长。

首先,我尝试按以下方式传递值:

df = df.as_matrix()
print stats.friedmanchisquare([df[x, :] for x in np.arange(df.shape[0])])

但我明白了:

ValueError: 
Less than 3 levels.  Friedman test not appropriate.

第二次,我也尝试不将其转换为矩阵形式,将其作为DataFrame(这对我来说很理想),但我想这还不支持,或者我在做错了:

print stats.friedmanchisquare([row for index, row in df.iterrows()])

这也给了我错误:

ValueError: 
Less than 3 levels.  Friedman test not appropriate.

所以,我的问题是:基于df将参数传递给stats.friedmanchisquare的正确方法是什么? (或甚至使用其df.as_matrix()表示)

您可以使用csv格式here下载我的数据框,并使用以下方式阅读:

df = pd.read_csv('df.csv', header=0, index_col=0)

感谢您的帮助:)

解决方案:

基于@Ami Tavory和@ vicg的答案(请对它们进行投票),根据数据的矩阵表示,我的问题的解决方案是添加* - 运算符defined here ,但是better explained here,如下:

df = df.as_matrix()
print stats.friedmanchisquare(*[df[x, :] for x in np.arange(df.shape[0])])

如果您想使用原始数据框,这也是如此,这是我理想的想法:

print stats.friedmanchisquare(*[row for index, row in df.iterrows()])

以这种方式,您以原生格式迭代数据帧。

注意我继续进行了一些timeit次测试,看看哪种方式更快,事实证明,事先将其首先转换为numpy array比原始数据帧格式中使用df快两倍

这是我的实验设置:

import timeit

setup = '''
import pandas as pd
import scipy.stats as stats
import numpy as np
df = pd.read_csv('df.csv', header=0, index_col=0)
'''

theCommand = '''
df = np.array(df)
stats.friedmanchisquare(*[df[x, :] for x in np.arange(df.shape[0])])
'''

print min(timeit.Timer(stmt=theCommand, setup=setup).repeat(10, 10000))

theCommand = '''
stats.friedmanchisquare(*[row for index, row in df.iterrows()])
'''

print min(timeit.Timer(stmt=theCommand, setup=setup).repeat(10, 10000))

产生以下结果:

4.97029900551
8.7627799511

2 个答案:

答案 0 :(得分:2)

我第一次尝试时遇到的问题是,您最终会传递一个包含多个数据帧的列表。

stats.friedmanchisquare需要多个array_like参数,而不是一个列表

尝试使用* (star/unpack)运算符解压缩列表

喜欢这个

df = df.as_matrix()
print stats.friedmanchisquare(*[df[x, :] for x in np.arange(df.shape[0])])

答案 1 :(得分:1)

你可以使用"star operator"传递它,类似于:

a = np.array([[1, 2, 3], [2, 3, 4] ,[4, 5, 6]])
friedmanchisquare(*(a[i, :] for i in range(a.shape[0])))