繁体   English   中英

如何计算2d中数组元素之间差异的所有组合?

[英]How to calculate all combinations of difference between array elements in 2d?

给定一个数组arr = [10, 11, 12]我想计算一个元素可以从另一个元素中减去的所有方法。 对于1xN阵列,所需输出是NxN阵列,其中output[i, j] = arr[i] - arr[j] 我的方法是生成两个数字的所有可能的配对,减去和重塑。 如下

opts = np.array(list(product(arr, arr)))
[[10 10] 
 [10 11]
 [10 12]
 [11 10]
 [11 11]
 [11 12]
 [12 10]
 [12 11]
 [12 12]]
 diffs = (opts[:, 0] - opts[:, 1]).reshape(len(arr), -1)
 [[ 0 -1 -2]
  [ 1  0 -1]
  [ 2  1  0]]

这很好用,我接下来要做的是将它推广到2d输入。 基本上我想要完成的是给出一个MxN数组来输出一个MxNxN数组,并且对于每一层(深度方向),为每一行执行上述功能。

我试图将MxN输入数组重新MxNx1MxNx1 ,然后像以前一样计算产品。 我的假设是,它会像以前一样在元素方面表现,遗憾的是没有。

我的第一个想法是初始化适当形状的输出并循环遍历行并“手动”设置值,但我希望采用矢量化方法。 有没有人知道如何在不绕过数千行的情况下在2维中完成此操作?

这是一种通用的矢量化方式,涵盖了在将输入数组重新映射为可广播的shpaes之后利用broadcasting 1D和2D情况 -

def permute_axes_subtract(arr, axis):
    # Get array shape
    s = arr.shape

    # Get broadcastable shapes by introducing singleton dimensions
    s1 = np.insert(s,axis,1)
    s2 = np.insert(s,axis+1,1)

    # Perform subtraction after reshaping input array to 
    # broadcastable ones against each other
    return arr.reshape(s1) - arr.reshape(s2)

要执行任何其他的elementwise ufunc操作,只需用它取代了减法运算。

样品运行 -

In [184]: arr = np.random.rand(3)

In [185]: permute_axes_subtract(arr, axis=0).shape
Out[185]: (3, 3)

In [186]: arr = np.random.rand(3,4)

In [187]: permute_axes_subtract(arr, axis=0).shape
Out[187]: (3, 3, 4)

In [188]: permute_axes_subtract(arr, axis=1).shape
Out[188]: (3, 4, 4)

@ ClimbingTheCurve上发布的解决方案func - permute_difference和在大型2D阵列上发布的解决方案 -

In [189]: arr = np.random.rand(100,100)

In [190]: %timeit permute_difference(arr, axis=0)
     ...: %timeit permute_axes_subtract(arr, axis=0)
1 loop, best of 3: 295 ms per loop
1000 loops, best of 3: 1.17 ms per loop

In [191]: %timeit permute_difference(arr, axis=1)
     ...: %timeit permute_axes_subtract(arr, axis=1)
1 loop, best of 3: 303 ms per loop
1000 loops, best of 3: 1.12 ms per loop

解决方案是为1d情况编写函数,并且为了概括使用函数np.apply_along_axis() ,该函数接受函数,应用轴和输入数组。 这完全符合预期。 我用过的代码:

from itertools import product

import numpy as np


def permute_difference(arr, axis=1):
    """
    applies the _permute_difference to a 2d array
    along the specified axis

    Parameters
    ----------
    arr numpy.array

    Returns
    -------
    numpy.array
        a 3d array, each 2d array the i^th along the depth
        contains the permuted difference of the i^th row
        in the input array
    """
    def _permute_difference(arr):
        """
        calculates all the differences between all combinations
        terms in the input array. output[i,j] = arr[i] - arr[j]
        for every combination if ij.

        Parameters
        ----------
        arr numpy.array
            a 1d input array

        Returns
        -------
        numpy.array
            a 2d array

        Examples
        --------
        arr = [10, 11, 12]

        diffs = [[ 0 -1 -2]
                [ 1  0 -1]
                [ 2  1  0]]
        """
        opts = np.array(list(product(arr, arr)))
        d = (opts[:, 0] - opts[:, 1]).reshape(len(arr), -1)
        return d

    if arr.ndim == 1:
        diffs = _permute_difference(arr)
    else:
        diffs = np.apply_along_axis(permute_difference, axis, arr)
    return diffs

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM