在Python中读取矩阵并获取行名和列名

gth*_*thm 3 numpy python-2.7 pandas

我想读取一个矩阵文件,如下所示:

sample  sample1 sample2 sample3
sample1 1   0.7 0.8
sample2 0.7 1   0.8
sample3 0.8 0.8 1
Run Code Online (Sandbox Code Playgroud)

我想获取所有值 > 0.8 的对。例如:sample1,sample3 0.8 sample2,sample3 0.8大文件中的等。

当我使用 时csv.reader,每一行都会变成一个列表,并跟踪行和列名称使程序变得危险。我想知道一种优雅的方法,例如使用numpyor pandas

期望的输出:

sample1,sample3 0.8 
sample2,sample3 0.8
Run Code Online (Sandbox Code Playgroud)

1 可以忽略,因为在同一样本之间,它始终为 1。

And*_*den 5

您可以使用以下方法屏蔽掉上三角值np.triu

In [11]: df
Out[11]:
         sample1  sample2  sample3
sample
sample1      1.0      0.7      0.8
sample2      0.7      1.0      0.8
sample3      0.8      0.8      1.0

In [12]: np.triu(df, 1)
Out[12]:
array([[ 0. ,  0.7,  0.8],
       [ 0. ,  0. ,  0.8],
       [ 0. ,  0. ,  0. ]])

In [13]: np.triu(df, 1) >= 0.8
Out[13]:
array([[False, False,  True],
       [False, False,  True],
       [False, False, False]], dtype=bool)
Run Code Online (Sandbox Code Playgroud)

然后要提取正确的索引/列,我认为您必须使用np.where*:

In [14]: np.where(np.triu(df, 1) >= 0.8)
Out[14]: (array([0, 1]), array([2, 2]))
Run Code Online (Sandbox Code Playgroud)

这为您提供了第一个索引索引和列索引的数组(这是此 numpy 版本中效率最低的部分):

In [16]: index, cols = np.where(np.triu(df, 1) >= 0.8)

In [17]: [(df.index[i], df.columns[j], df.iloc[i, j]) for i, j in zip(index, cols)]
Out[17]:
[('sample1', 'sample3', 0.80000000000000004),
 ('sample2', 'sample3', 0.80000000000000004)]
Run Code Online (Sandbox Code Playgroud)

如预期的。

*我可能忘记了获取最后一块的更简单的方法(编辑:下面的pandas代码可以做到这一点,但我认为可能还有另一种方法。)


您可以在 pandas 中使用相同的技巧,但使用堆栈来本地获取索引/列:

In [21]: (np.triu(df, 1) >= 0.8) * df
Out[21]:
         sample1  sample2  sample3
sample
sample1        0        0      0.8
sample2        0        0      0.8
sample3        0        0      0.0

In [22]: res = ((np.triu(df, 1) >= 0.8) * df).stack()

In [23]: res
Out[23]:
sample
sample1  sample1    0.0
         sample2    0.0
         sample3    0.8
sample2  sample1    0.0
         sample2    0.0
         sample3    0.8
sample3  sample1    0.0
         sample2    0.0
         sample3    0.0
dtype: float64

In [24]: res[res!=0]
Out[24]:
sample
sample1  sample3    0.8
sample2  sample3    0.8
dtype: float64
Run Code Online (Sandbox Code Playgroud)