【问题标题】:Creating this numpy array in Python在 Python 中创建这个 numpy 数组
【发布时间】:2020-02-12 17:20:46
【问题描述】:

我有以下 numpy 数组

import numpy as np
a = np.array([1,2,6,8])

我想从 a 创建另一个 numpy 数组,以便它包含 a 的两个元素的所有不同可能总和。很容易证明存在int(a.size*(a.size-1)/2) 不同的可能总和,由以下各项组成:

a[0] + a[1]
a[0] + a[2]
a[0] + a[3]
a[1] + a[2]
a[1] + a[3]
a[2] + a[3]

如何在不使用双 for 循环的情况下以上述总和作为元素构造一个 numpy 数组(我能想到的唯一方法)。对于上面的例子,输出应该是[3,7,9,8,10,14]

MWE

eff = int(a.size*(a.size-1)/2)
c = np.empty((0, eff))

【问题讨论】:

    标签: python arrays numpy numpy-ndarray


    【解决方案1】:

    你可以使用triu_indices:

    i0,i1 = np.triu_indices(4,1)
    a[i0]
    # array([1, 1, 1, 2, 2, 6])
    a[i1]
    # array([2, 6, 8, 6, 8, 8])
    a[i0]+a[i1]
    # array([ 3,  7,  9,  8, 10, 14])
    

    对于更多术语,我们需要构建自己的“nd_triu_idx”。以下是如何为 5 个列表中的 3 个术语执行此操作:

    n = 5
    full = np.mgrid[:n,:n,:n]
    nd_triu_idx = full[:,(np.diff(full,axis=0)>0).all(axis=0)]
    nd_triu_idx
    # array([[0, 0, 0, 0, 0, 0, 1, 1, 1, 2],
    #        [1, 1, 1, 2, 2, 3, 2, 2, 3, 3],
    #        [2, 3, 4, 3, 4, 4, 3, 4, 4, 4]])
    

    要完全概括术语的数量,请使用类似

    k = 4
    full = np.mgrid[k*(slice(n),)]
    

    等等

    【讨论】:

    • 这太棒了!它可以很容易地适应找到三个元素和的所有组合吗?
    • 因此,对于 OP 中显示的数组的三个元素的总和,我希望看到类似 [9,11,15,16] 的内容。如何从您更新的代码中明确获取此信息?以及它如何推广到更多术语(问题的最大术语数为 4)
    • @Sid 在这种情况下,您必须将 n=5 替换为 n=4 并添加为最后一行 a[nd_triu_idx].sum(axis=0)
    • @PaulPanzer,谢谢。最后,如果我想在 5 个列表中的 4 个术语中执行此操作,我会只更改前两行吗? n = 5full = np.mgrid[:n,:n,:n,:n]?如果是这样,有没有办法指定术语数量和列表大小的结果?
    • @Sid 如果您不关心总和的顺序,获取所有总和的最简单方法是np.unpackbits(np.arange(1024,dtype='<u2')[:,None].view('u1'),axis=1,count=10,bitorder='little')@a
    【解决方案2】:

    您可以对大小为 2 的数组进行组合并对每个数组求和:

    import numpy as np
    from itertools import combinations
    
    a = np.array([1,2,6,8])
    
    print(list(map(sum, combinations(a, 2))))
    # [3, 7, 9, 8, 10, 14]
    

    或者使用 numpy:

    import numpy as np
    
    a = np.array([1,2,6,8,1])
    
    b = a + a[:,None]
    print(b[np.triu_indices(4, 1)])
    # [ 3  7  9  8 10 14]
    

    【讨论】:

    • 既然我要用列表,可以写b = list(map(sum, combinations(a, 2)))吗?
    • 如果你想返回一个 NumPy 数组,np.fromiter() 的好案例:np.fromiter(map(sum, it.combinations(a, 2)), dtype=a.dtype)
    • 我收到TypeError: 'list' object is not callable 错误。
    • @Sid,确保您没有将您的列表命名为 list
    • @Sid,您之前定义了一些列表,其中包含我在代码中使用的一些内置函数。它可以是listmap。请检查。
    【解决方案3】:

    如何计算a 的指数版本的笛卡尔积?

    >>> a = np.array([1, 2, 6, 8])[:, None]
    >>> b = np.exp(a)
    >>> np.unique(np.tril(np.log(np.dot(b, b.T)), k=-1))[1:]
    array([ 3.,  7.,  8.,  9., 10., 14.])
    

    【讨论】:

    • 这没有正确的长度。应该是 1 x 6 数组
    • 这不太对(仍然有一个额外的零),但相当聪明(而且令人费解),所以 +1
    猜你喜欢
    • 2015-06-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-12-27
    • 1970-01-01
    • 2013-01-21
    • 1970-01-01
    • 2016-02-08
    相关资源
    最近更新 更多