计算numpy数组中的列对的组合

时间:2018-01-28 07:24:37

标签: python arrays numpy

我有一个矩阵,其中包含一定数量的列,只包含数字0和1,我想计算[0,0],[0,1],[1,0]和[1]的数量,每列的一对列.1,

例如,如果我有一个包含四列的矩阵,我想计算第一列和第二列中的00s,11s,01s和11s的数量,将最终结果附加到列表中,然后循环遍历第3和第4列并将该答案附加到列表中。

示例输入:

array([[0, 1, 1, 0],
       [1, 0, 1, 0],
       [0, 1, 0, 1],
       [0, 0, 1, 1],
       [1, 1, 0, 0]])

我的预期输出是:

array([[1, 1],
       [2, 1],
       [1, 2],
       [1, 1]])

说明:

前两列有[0,0]一次。后两列也有[0,0]一次。前两列有[0,1]两次,后两列有[0,1]一次......依此类推。

这是我最近的尝试,似乎有效。想要反馈。

# for each pair of columns calculate haplotype frequencies
# haplotypes:
# h1 = 11
# h2 = 10
# h3 = 01
# h4 = 00
# takes as input a pair of columns
def calc_haplotype_freq(matrix):
    h1_frequencies = []
    h2_frequencies = []
    h3_frequencies = []
    h4_frequencies = []
    colIndex1 = 0
    colIndex2 = 1
    for i in range(0, 2): # number of columns divided by 2
        h1 = 0
        h2 = 0
        h3 = 0
        h4 = 0
        column_1 = matrix[:, colIndex1]
        column_2 = matrix[:, colIndex2]
        for row in range(0, matrix.shape[0]):
            if (column_1[row, 0] == 1).any() & (column_2[row, 0] == 1).any():
                h1 += 1
            elif (column_1[row, 0] == 1).any() & (column_2[row, 0] == 0).any():
                h2 += 1
            elif (column_1[row, 0] == 0).any() & (column_2[row, 0] == 1).any():
                h3 += 1
            elif (column_1[row, 0] == 0).any() & (column_2[row, 0] == 0).any():
                h4 += 1
        colIndex1 += 2
        colIndex2 += 2
        h1_frequencies.append(h1)
        h2_frequencies.append(h2)
        h3_frequencies.append(h3)
        h4_frequencies.append(h4)
    print("H1 Frequencies (11): ", h1_frequencies)
    print("H2 Frequencies (10): ", h2_frequencies)
    print("H3 Frequencies (01): ", h3_frequencies)
    print("H4 Frequencies (00): ", h4_frequencies)

对于上面的示例输入,这给出:

----------
H1 Frequencies (11):  [1, 1]
H2 Frequencies (10):  [1, 2]
H3 Frequencies (01):  [2, 1]
H4 Frequencies (00):  [1, 1]
----------

哪个是正确的,但还有更好的方法吗?如何从函数中返回这些结果以进行进一步处理?

1 个答案:

答案 0 :(得分:2)

从此开始 -

x
array([[0, 1, 1, 0],
       [1, 0, 1, 0],
       [0, 1, 0, 1],
       [0, 0, 1, 1],
       [1, 1, 0, 0]])

将数组拆分为2列组并连接它们:

y = x.T
z = np.concatenate([y[i:i + 2] for i in range(0, y.shape[0], 2)], 1).T

现在,进行广播比较并总结:

(z[:, None] == [[0, 0], [0, 1], [1, 0], [1, 1]]).all(2).sum(0)
array([2, 3, 3, 2])

如果您想要每列对数,那么您可以执行以下操作:

def calc_haplotype_freq(x):
    counts = []
    for i in range(0, x.shape[1], 2):
        counts.append(
             (x[:, None, i:i + 2] == [[0, 0], [0, 1], [1, 0], [1, 1]]).all(2).sum(0)
        )

    return np.column_stack(counts)

calc_haplotype_freq(x)
array([[1, 1],
       [2, 1],
       [1, 2],
       [1, 1]])