[英]How to calculate all combinations of difference between array elements in 2d?
Given an array arr = [10, 11, 12]
I want to calculate all the ways that one element can be subtracted from another. 给定一个数组
arr = [10, 11, 12]
我想计算一个元素可以从另一个元素中减去的所有方法。 For a 1xN
array the desired output is a NxN array where output[i, j] = arr[i] - arr[j]
. 对于
1xN
阵列,所需输出是NxN阵列,其中output[i, j] = arr[i] - arr[j]
。 My approach was to generate all the possible pairings of two numbers, subtract, and reshape. 我的方法是生成两个数字的所有可能的配对,减去和重塑。 As follows
如下
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]]
This works quite nicely, what I would like to do next is to generalize this to a 2d input. 这很好用,我接下来要做的是将它推广到2d输入。 Essentially what I would like to accomplish is given an
MxN
array to output an MxNxN
array, and for each layer (depth-wise) perform the above functionality for each row. 基本上我想要完成的是给出一个
MxN
数组来输出一个MxNxN
数组,并且对于每一层(深度方向),为每一行执行上述功能。
I attempted to reshape the MxN
input array to be MxNx1
and then calculate the product as before. 我试图将
MxN
输入数组重新MxNx1
为MxNx1
,然后像以前一样计算产品。 My assumption was that it would behave element-wise the same as before, unfortunately not. 我的假设是,它会像以前一样在元素方面表现,遗憾的是没有。
My first thought is to initialize an output of the appropriate shape and loop over the rows and set the values "manually" but I was hoping for a vectorized approach. 我的第一个想法是初始化适当形状的输出并循环遍历行并“手动”设置值,但我希望采用矢量化方法。 Does anyone know how I can accomplish this in 2 dimensions without looping over thousands of rows?
有没有人知道如何在不绕过数千行的情况下在2维中完成此操作?
Here's a generic vectorized way to cover both 1D and 2D cases leveraging broadcasting
after reshaping the input array to broadcastable shpaes against each other - 这是一种通用的矢量化方式,涵盖了在将输入数组重新映射为可广播的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)
To perform any other elementwise ufunc
operation, simply replace the subtraction operation with it. 要执行任何其他的elementwise
ufunc
操作,只需用它取代了减法运算。
Sample run - 样品运行 -
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)
Timings on @ClimbingTheCurve's posted solution func - permute_difference
and the one posted in this one on large 2D
arrays - @ 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
The solution is to write a function for the 1d case and in order to generalize use the function np.apply_along_axis()
which takes a function, an axis to apply along, and an input array. 解决方案是为1d情况编写函数,并且为了概括使用函数
np.apply_along_axis()
,该函数接受函数,应用轴和输入数组。 This works exactly as intended. 这完全符合预期。 The code I used:
我用过的代码:
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.