Python 对numpy数组中的列对进行组合计数

Python 对numpy数组中的列对进行组合计数,python,arrays,numpy,Python,Arrays,Numpy,我有一个矩阵,有一定数量的列,其中只包含数字0和1,我想计算每对列中[0,0]、[0,1]、[1,0]和[1,1]的数量 例如,如果我有一个四列的矩阵,我想计算第一列和第二列中的00、11、01和11的数量,将最终结果附加到列表中,然后循环第三列和第四列,并将答案附加到列表中 输入示例: array([[0, 1, 1, 0], [1, 0, 1, 0], [0, 1, 0, 1], [0, 0, 1, 1], [1, 1, 0, 0]])

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

例如,如果我有一个四列的矩阵,我想计算第一列和第二列中的00、11、01和11的数量,将最终结果附加到列表中,然后循环第三列和第四列,并将答案附加到列表中

输入示例:

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]
----------
这是正确的,但是有更好的方法吗?如何从函数返回这些结果以进行进一步处理?

从以下内容开始-

x
array([[0, 1, 1, 0],
       [1, 0, 1, 0],
       [0, 1, 0, 1],
       [0, 0, 1, 1],
       [1, 1, 0, 0]])
将数组拆分为两列组成的组,并连接它们:

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]])

哇,太棒了。但是,我不需要所有列的总和,我需要能够看到下游处理的所有列对的唯一组合数。我实际上能够解决我的问题,但是,我想知道是否有一种方法可以用你的方式来解决?PS:谢谢您的回复@Carlos[2,3,3,2]是[0,0]的组合数;[0, 1]; [1, 0]; 分别为[1,1]。这不是你想要的吗?@COLDSPEED是和否,组合的数量可以是每列对,因此正确的答案是[1,1,2,1]对于第1列和第2列,以及[1,2,1,1]对于第3列和第4列。请看我的编辑。您的总数是正确的,但必须单独返回以进行进一步的下游分析。@COLDSPEED是的,您已经解决了,非常感谢!真不敢相信我花了四个小时试图让它发挥作用,哈哈。@Carlos我相信这是朝着正确的方向迈出的一步,但就性能而言,我不确定离最好的有多远。不过,如果你对此感到满意,那就太酷了。祝你工作顺利!