我正在尝试将值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
答案 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])))