Mann-Whitney U 检验是零假设的非参数检验,即样本 x 的分布与样本 y 的分布相同。它通常被用作分布之间位置差异的测试。
有关 Mann-Whitney 检验的更多说明,请参见 https://en.wikipedia.org/wiki/Mann–Whitney_U_test。粗略地说,您可能感兴趣的是被观察的不同类型物体之间出现绿点和蓝点的统计差异。考虑到数据的性质和分布,讨论这个统计数据的适用性,我理解这超出了这个问题的范围。
如果您需要从 CSV 文件读取数据,按照您呈现的方式格式化,您可以使用以下内容。 '\s+' 的分隔符将匹配所有空格。
import pandas
import scipy.stats
import itertools
# The CSV data is not comma-separated, so not really comma-separated.
# This uses whitespace as a separator.
data = pandas.read_csv('data.csv', sep='\s+')
# Generate all unique combinations of values of the second column.
# Having these ahead of time would save going over the data multiple times,
# but the idea is to infer these automatically.
combinations = list(itertools.combinations(data[data.columns[1]].unique(), 2))
for key, group in data.groupby(data.columns[0]):
for c in combinations:
# Select values for each element of the combination.
select_x = group[data.columns[1]] == c[0]
select_y = group[data.columns[1]] == c[1]
x = group[select_x][data.columns[2]]
y = group[select_y][data.columns[2]]
mwu = scipy.stats.mannwhitneyu(x, y)
print(f'{data.columns[0]}: {key} ({c[0]} vs {c[1]}): {mwu}')
这将打印:
Type: A (Blue vs Green): MannwhitneyuResult(statistic=19.0, pvalue=0.534965034965035)
Type: B (Blue vs Green): MannwhitneyuResult(statistic=41.0, pvalue=0.151981351981352)
Type: C (Blue vs Green): MannwhitneyuResult(statistic=41.0, pvalue=0.151981351981352)
首先,我在推断类型和类,因为这部分问题的解释方式:
这个想法是对类型自动执行,所以我得到了 A、B、C 等的 p 值。
提前知道类型可以用来提高代码的效率,但我故意不硬编码任何类,如“A”、“B”、“C”或斑点的颜色由于上述问题作者的这一要求.此要求可能需要多次检查数据,因为需要这些数据来确定 groupby 类的组合。
groupby 的文档可以在 https://pandas.pydata.org/docs/reference/api/pandas.DataFrame.groupby.html 下找到。
解释
首先,我在第二列 (data.columns[1]) 中生成唯一值的所有组合。在你的情况下,这就是颜色。你只有“绿色”和“蓝色”,但我认为可以有更多,所以我没有对它们进行硬编码。然后,我按第一列(在您的情况下为“类型”)对数据进行分组:data.groupby(data.columns[0])。每个groupby 返回一个键,它是分组的值(您的类型),以及该组中的值(group)。然后,对于组合的每个元素(select_x 和select_y),为 Mann-Whitney 检验的 X 和 Y 值选择第三列中的值(在您的情况下为“点”)。这些是pandas.core.series.Series 类型的对象,它包含指定要选择的元素的布尔值。您也可以通过简单地使用data.columns[] 来打印列的名称,这样我也不需要硬编码第一列的名称(“类型”)。
此代码应该与列的名称无关。它通过将在第一列中找到的所有唯一值分组并从第二列生成唯一值的所有组合来自动执行您要求的统计测试,以便从第三列中选择实际测量值。
如您所见,它们可能出现故障,这是由于我们使用了一组。我认为这不是问题,但如果是,请先对它们进行排序:
types = sorted(set(df['Type']))
您也可以使用 Panda 的groupby 和unique。但是我认为没有一种直接的方法可以选择所有组对,这似乎是您需要的。但是,Pandas 确实能够指定多个列作为分组依据。