将成对距离的长格式数据帧转换为python中的距离矩阵

fru*_*ian 8 python matrix pandas pairwise

我有一个成对距离的 pandas 数据框,其形式为:

    SampleA   SampleB  Num_Differences
0  sample_1  sample_2                1
1  sample_1  sample_3                4
2  sample_2  sample_3                8
Run Code Online (Sandbox Code Playgroud)

请注意,没有自我比较(例如,不会表示sample_1 与sample_1)。我想将此表转换为方形距离矩阵,如下所示:

            sample_1      sample_2  sample_3
sample_1                       1              4
sample_2         1                            8
sample_3         4             8    
Run Code Online (Sandbox Code Playgroud)

任何人都可以给我一些关于如何在 python 中进行此类转换的指示吗?该问题类似于 R 中的上一个问题(将成对距离转换为 R 中的距离矩阵),但我不知道要使用相应的 python 函数。这个问题似乎也与这个问题相反(Convert a distance matrix to a list ofpairwise distances in Python)。

以我正在使用的形式重现数据框的一些代码:

    SampleA   SampleB  Num_Differences
0  sample_1  sample_2                1
1  sample_1  sample_3                4
2  sample_2  sample_3                8
Run Code Online (Sandbox Code Playgroud)

moz*_*way 5

您可以将形状重塑为正方形,然后通过添加转置值来使其对称:

# make unique, sorted, common index
idx = sorted(set(df['SampleA']).union(df['SampleB']))

# reshape
(df.pivot(index='SampleA', columns='SampleB', values='Num_Differences')
   .reindex(index=idx, columns=idx)
   .fillna(0, downcast='infer')
   .pipe(lambda x: x+x.values.T)
 )
Run Code Online (Sandbox Code Playgroud)

或者,您可以使用有序分类索引并在使用 重塑期间保留 NA pivot_table。然后添加转置后的值以使其对称:

cat = sorted(set(df['SampleA']).union(df['SampleB']))

(df.assign(SampleA=pd.Categorical(df['SampleA'],
                                  categories=cat,
                                  ordered=True),
           SampleB=pd.Categorical(df['SampleB'],
                                  categories=cat,
                                  ordered=True),
           )
    .pivot_table(index='SampleA',
                 columns='SampleB',
                 values='Num_Differences',
                 dropna=False, fill_value=0)
    .pipe(lambda x: x+x.values.T)
)
Run Code Online (Sandbox Code Playgroud)

输出:

SampleB   sample_1  sample_2  sample_3
SampleA                               
sample_1         0         1         4
sample_2         1         0         8
sample_3         4         8         0
Run Code Online (Sandbox Code Playgroud)