【问题标题】:Computing mean for non-unique elements of numpy array pairs计算 numpy 数组对的非唯一元素的平均值
【发布时间】:2012-05-02 08:25:07
【问题描述】:

我有三个数组,大小都一样:

arr1 = np.array([1.4, 3.0, 4.0, 4.0, 7.0, 9.0, 9.0, 9.0])
arr2 = np.array([2.3, 5.0, 2.3, 2.3, 4.0, 6.0, 5.0, 6.0])
data = np.array([5.4, 7.1, 9.5, 1.9, 8.7, 1.8, 6.1, 7.4])

arr1 可以占用任何浮点值,而 arr2 只能占用几个浮点值。我想获得 arr1 和 arr2 的唯一对,例如

arr1unique = np.array([1.4, 3.0, 4.0, 7.0, 9.0, 9.0])
arr2unique = np.array([2.3, 5.0, 2.3, 4.0, 6.0, 5.0])

对于每个非唯一对,我需要平均 data-array 中的相应元素,例如因为(arr1[3], arr2[3])(arr1[4], arr2[4]) 是相等的,所以取值 9.5 和 1.9 的平均值。与索引 6 和 8 对应的数据中的值也是如此。因此数据数组变为

dataunique = np.array([5.4, 7.1, 5.7, 8.7, 4.6, 6.1])

【问题讨论】:

    标签: python numpy


    【解决方案1】:

    这是解决问题的“纯 numpy”解决方案。纯 numpy 引号,因为它依赖于我仍在研究的 numpy 增强提案,但您可以在此处找到完整代码:

    http://pastebin.com/c5WLWPbp

    group_by((arr1, arr2)).mean(data)
    

    瞧,问题解决了。比任何已发布的解决方案都要快;而且更优雅,如果我自己可以这么说的话;)。

    【讨论】:

      【解决方案2】:

      defaultdict 可以在这里为您提供帮助:

      >>> import numpy as np
      >>> arr1 = np.array([1.4, 3.0, 4.0, 4.0, 7.0, 9.0, 9.0, 9.0])
      >>> arr2 = np.array([2.3, 5.0, 2.3, 2.3, 4.0, 6.0, 5.0, 6.0])
      >>> data = np.array([5.4, 7.1, 9.5, 1.9, 8.7, 1.8, 6.1, 7.4])
      >>> from collections import defaultdict
      >>> dd = defaultdict(list)
      >>> for x1, x2, d in zip(arr1, arr2, data):
      ...   dd[x1, x2].append(d)
      ... 
      >>> arr1unique = np.array([x[0] for x in dd.iterkeys()])
      >>> arr2unique = np.array([x[1] for x in dd.iterkeys()])
      >>> dataunique = np.array([np.mean(x) for x in dd.itervalues()])
      >>> print arr1unique
      [ 1.4  7.   4.   9.   9.   3. ]
      >>> print arr2unique
      [ 2.3  4.   2.3  5.   6.   5. ]
      >>> print dataunique
      [ 5.4  8.7  5.7  6.1  4.6  7.1]
      

      这个方法给出了你的答案,但破坏了排序。如果顺序很重要,你可以用collections.OrderedDict做基本相同的事情

      【讨论】:

      • 谢谢!我以前不知道收藏库。我这里没有python 2.7(所以我不能使用OrderedDict),但是顺序并不重要。
      【解决方案3】:

      从 arr1 中创建一个字典作为键,并将其等效的 arr2 存储为值。对于每个保存到字典的数据,都会生成其唯一的数据条目。如果键已经存在,则跳过该迭代并继续。

      【讨论】:

        【解决方案4】:

        您所要做的就是创建一个OrderedDict 以将键存储为 (arr1,arr2) 中的一对元素,并将值存储为数据中的元素列表。对于任何重复键(arr1 和 arr2 对),重复条目将存储在列表中。然后,您可以重新遍历字典中的值并创建平均值。要获取唯一键,只需遍历键并拆分元组

        试试下面的

        >>> d=collections.OrderedDict()
        >>> for k1,k2,v in zip(arr1,arr2,data):
            d.setdefault((k1,k2),[]).append(v)      
        >>> np.array([np.mean(v) for v in d.values()])
        array([ 5.4,  7.1,  5.7,  8.7,  4.6,  6.1])
        
        >>> arr1unique = np.array([e[0] for e in d])
        >>> arr2unique = np.array([e[1] for e in d])
        

        【讨论】:

        • 很好很简短,尽管由于某种原因我们这里仍然没有 python 2.7。我将不得不坚持@wim 的解决方案。