Python 中 Kruskal-Wallis 测试的输入格式
Posted
技术标签:
【中文标题】Python 中 Kruskal-Wallis 测试的输入格式【英文标题】:Input format for Kruskal-Wallis test in Python 【发布时间】:2015-08-03 03:35:25 【问题描述】:我正在比较癌症患者和健康人的 DNA 结构断裂区域。我正在尝试对每个区域的中断次数进行 Kruskal-Wallis 测试(SciPy Stats),以查看两个分布之间是否存在差异。 我不确定 Kruskal - Wallis 的输入应该是数组(文档)还是数组列表(互联网上的其他地方)。
首先,我尝试了一个这样的样本+控制数组:
controls = ['1', '2', '3', '4', '5']
samples = ['10', '20', '30', '40', '50']
n=0
for item in controls:
array_item = np.array([item, samples[n]])
kw_test = stats.mstats.kruskalwallis(array_item)
print(kw_test)
n+=1
这给了我所有项目的以下输出:
(0.0, nan)
我还尝试将单个数据点转换为数组,然后运行 KW 测试。
controls = ['1', '2', '3', '4', '5']
samples = ['10', '20', '30', '40', '50']
n=0
kw_results = []
for item in controls:
array_controls = np.array([item])
array_samples = np.array([samples[n]])
kw_test = stats.mstats.kruskalwallis(array_samples, array_controls)
kw_results.append(kw_test)
n+=1
print(kw_results)
即使我大幅更改了其中一个列表,所有比较的结果都是 (1.0, 0.31731050786291404)
。
深入挖掘,我读到输入应该是一个数组列表,所以我认为只给出两个数据点(一个样本,一个控件)可能会导致“(0.0,nan)”,所以我尝试了好吧。
controls = ['1', '2', '3', '4', '5']
samples = ['10', '20', '30', '40', '50']
list_ = []
n=0
for item in controls:
array_item = np.array([item, samples[n]])
list_.append(array_item)
n+=1
kw_test = stats.mstats.kruskalwallis(list_)
print(kw_test)
这给了我这个错误:
TypeError: Not implemented for this type
现在我不确定要使用什么格式/类型,希望任何人都可以帮助我!
【问题讨论】:
【参考方案1】:scipy.stats.mstats.kruskalwallis 模块使用数组。这些可以是具有奇数个观察值的数组。
如果您将 CSV 文件中的数据分列在不同的列中,这样的操作应该可以:
import pandas
from scipy.stats import mstats
Data = pandas.read_csv("CSVfile.csv")
Col_1 = Data['Colname1']
Col_2 = Data['Colname2']
Col_3 = Data['Colname3']
Col_4 = Data['Colname4']
print("Kruskal Wallis H-test test:")
H, pval = mstats.kruskalwallis(Col_1, Col_2, Col_3, Col_4)
print("H-statistic:", H)
print("P-Value:", pval)
if pval < 0.05:
print("Reject NULL hypothesis - Significant differences exist between groups.")
if pval > 0.05:
print("Accept NULL hypothesis - No significant difference between groups.")
【讨论】:
我试图完全这样做,但它给出了错误 TypeError:float() 参数必须是字符串或数字,而不是“SingleBlockManager”。有什么想法吗? 在我的情况下,没有列是动态的,我可以获得 3-10 列。如何处理这种情况【参考方案2】:我认为 Kruskal Wallis 检验在所有情况下都给出相同 p 值的原因是因为您在每种情况下只比较两个值。
要将数组列表传递给 kruskal 测试,您似乎需要将其作为 mstats.kruskalwallis(*args) 传递。见 (create vectors for Kruskal-Wallis H-test python)
import pandas, sys
from scipy.stats import mstats
H, pval = mstats.kruskalwallis(*args)
controls = ['1', '2', '3', '4', '5']
samples = ['10', '20', '30', '70', '50']
n=0
kw_results = []
list_ = []
for item in controls:
array_item = np.array([item, samples[n]])
list_.append(array_item)
n+=1
args=[l for l in list_]
kw_test = mstats.kruskalwallis(*args)
print(kw_results)
如果您在列中有数据,Patrick 的修改很有用,但我无法将列表直接传递给 kruskal 函数,但传递它 *args 有效。
import pandas, sys
from scipy.stats import mstats
Data = pandas.read_csv(sys.argv[1], index_col=0, sep='\t')
args = [Data[col] for col in Data.columns]
H, pval = mstats.kruskalwallis(*args)
【讨论】:
【参考方案3】:Osian 的回答对我帮助很大。我想假设第一列是某种标识符,而不是数据,我还想让测试评估所有数据列,而无需手动输入列标题。以下是符合我标准的对 Osian 代码的修改。
import pandas, sys
from scipy.stats import mstats
Data = pandas.read_csv(sys.argv[1], index_col=0, sep='\t')
H, pval = mstats.kruskalwallis([Data[col] for col in Data.columns])
print "H-statistic:\t%s\nP-value:\t%s" % (str(H),str(pval))
if pval < 0.05:
print("Reject NULL hypothesis - Significant differences exist between groups.")
if pval > 0.05:
print("Accept NULL hypothesis - No significant difference between groups.")
【讨论】:
以上是关于Python 中 Kruskal-Wallis 测试的输入格式的主要内容,如果未能解决你的问题,请参考以下文章
4.1 Kruskal - Wallis 检验 ——python实战
如何处理 Matlab 中 Kruskal-Wallis 测试中的缺失值?