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

What is the correct way of passing parameters to stats.friedmanchisquare based on a DataFrame?

我正在尝试将值从具有形状 (11,17).

的数据框 df 传递到 stats.friedmanchisquare

这就是 对我有效(在本例中仅适用于三行):

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

产生

(16.714285714285694, 0.00023471398805908193)

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

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

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.

Second,我也尝试过不将其转换为矩阵形式,将其保留为 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 的回答(请对他们投票),基于数据的矩阵表示,我的问题的解决方案是添加 *-operator defined here, but 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

我在您的第一次尝试中看到的问题是您最终传递了一个包含多个数据框的列表。

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

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

像这样

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

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

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