如何使用Pandas将R的Tukey HSD表转换为相关矩阵

2 投票
2 回答
29 浏览
提问于 2025-04-12 12:12

我最近从R的TukeyHSD测试中导出了一个表格,目的是获取不同时间组(0, 5, 10, 20, 30, 40, 50, 60)的p值。我想知道有没有办法把这个表格转换成一个相关性矩阵,在这个矩阵中,每个轴代表时间组,并且对应各自的p值。

这个表格里有一个索引,用来表示不同时间组之间的对应关系(比如5-10或者10-50)。我已经把它导入到Python中,作为一个数据框。请问有没有办法像下面这样重新排列这个数据框呢?

        p adj
Groups  
50-0    2.815526e-13
60-0    2.855494e-13
20-0    4.764197e-08
50-5    1.712389e-05
50-10   1.483440e-04
50-40   1.643480e-04
60-5    5.873007e-04
60-10   5.218047e-03
60-40   5.613566e-03
10-0    6.878476e-03
40-0    1.270855e-02
20-5    7.380859e-02
50-20   1.574372e-01
40-20   3.264569e-01
20-10   3.369147e-01
5-0 3.816166e-01
60-50   7.301423e-01
60-20   8.503578e-01
10-5    9.731384e-01
40-5    9.820983e-01
40-10   1.000000e+00

我希望它能变成这样:

        0    5    10    20    ...
0       ...  ...  ...  ...
5       ...  ...  ...  ...
10      ...  ...  ...  ...
20      ...  ...  ...  ...
...

我在网上没有找到类似的东西,所以不知道从哪里开始。

2 个回答

0

只需创建一个数据框(dataframe),内容如下:

  • index:取原始数据框(df)索引的第一个分割的唯一值,从0开始。
  • columns:取原始数据框(df)索引的第二个分割的唯一值。
final = pd.DataFrame(
    {},
    index = df.index.map(lambda x: x.split('-')[0]).unique().map(lambda x: int(x)).sort_values(),
    columns = df.index.map(lambda x: x.split('-')[1]).unique().map(lambda x: int(x)).sort_values()
)

for i in final.index:
    for j in final.columns:
        try:
            final.loc[i, j] = df.loc[f'{i}-{j}', 'p adj']
        except:
            final.loc[i, j] = np.nan

输出结果:

Groups        0         5         10        20        40        50
Groups                                                            
5       0.381617       NaN       NaN       NaN       NaN       NaN
10      0.006878  0.973138       NaN       NaN       NaN       NaN
20           0.0  0.073809  0.336915       NaN       NaN       NaN
40      0.012709  0.982098       1.0  0.326457       NaN       NaN
50      0.281553  0.000017  0.000148  0.157437  0.000164       NaN
60           0.0  0.000587  0.005218  0.850358  0.005614  0.730142

然后,遍历最终数据框的每个位置(第i行,第j列),并使用原始数据框中动态创建的索引来填充这些值。

应该有一些更好的方法,可以充分利用pandas的向量化功能,这样就不需要依赖循环了。

1

试试这个:

df[["x", "y"]] = df.index.str.split("-", expand=True).to_frame().astype(int).values
print(pd.crosstab(df["x"], df["y"], df["p adj"], aggfunc="first"))

输出结果是:

y             0         5         10        20        40        50
x                                                                 
5   3.816166e-01       NaN       NaN       NaN       NaN       NaN
10  6.878476e-03  0.973138       NaN       NaN       NaN       NaN
20  4.764197e-08  0.073809  0.336915       NaN       NaN       NaN
40  1.270855e-02  0.982098  1.000000  0.326457       NaN       NaN
50  2.815526e-13  0.000017  0.000148  0.157437  0.000164       NaN
60  2.855494e-13  0.000587  0.005218  0.850358  0.005614  0.730142

撰写回答