在Numpy中从数组中创建对列表的有效方法

时间:2015-04-12 02:40:28

标签: python arrays numpy scipy

我有一个numpy数组x(n,4)形状)整数,如:

[[0 1 2 3],
[1 2 7 9],
[2 1 5 2],
...]

我想将数组转换为一对数组:

[0,1]
[0,2]
[0,3]
[1,2]
...

所以第一个元素与同一个子数组中的其他元素成对。我已经有了for-loop解决方案:

y=np.array([[x[j,0],x[j,i]] for i in range(1,4) for j in range(0,n)],dtype=int)

但由于在numpy数组上循环效率不高,我尝试slicing作为解决方案。我可以为每一列切片:

y[1]=np.array([x[:,0],x[:,1]]).T
# [[0,1],[1,2],[2,1],...] 

我可以为所有列重复此操作。我的问题是:

  1. 如何将y[2]追加到y[1],......这样形状为(N,2)
  2. 如果列数不小(在此示例中为4),如何才能优雅地找到y[i]
  3. 实现最终阵列的替代方法有哪些?

3 个答案:

答案 0 :(得分:6)

我能想到的最干净的方法是:

>>> x = np.arange(12).reshape(3, 4)
>>> x
array([[ 0,  1,  2,  3],
       [ 4,  5,  6,  7],
       [ 8,  9, 10, 11]])
>>> n = x.shape[1] - 1
>>> y = np.repeat(x, (n,)+(1,)*n, axis=1)
>>> y
array([[ 0,  0,  0,  1,  2,  3],
       [ 4,  4,  4,  5,  6,  7],
       [ 8,  8,  8,  9, 10, 11]])
>>> y.reshape(-1, 2, n).transpose(0, 2, 1).reshape(-1, 2)
array([[ 0,  1],
       [ 0,  2],
       [ 0,  3],
       [ 4,  5],
       [ 4,  6],
       [ 4,  7],
       [ 8,  9],
       [ 8, 10],
       [ 8, 11]])

这将生成两份数据,因此它不是最有效的方法。这可能是这样的:

>>> y = np.empty((x.shape[0], n, 2), dtype=x.dtype)
>>> y[..., 0] = x[:, 0, None]
>>> y[..., 1] = x[:, 1:]
>>> y.shape = (-1, 2)
>>> y
array([[ 0,  1],
       [ 0,  2],
       [ 0,  3],
       [ 4,  5],
       [ 4,  6],
       [ 4,  7],
       [ 8,  9],
       [ 8, 10],
       [ 8, 11]])

答案 1 :(得分:2)

Jaimie一样,我首先尝试了第一列的repeat,然后重新整形,但后来决定制作2个中间数组更简单,并hstack

x=np.array([[0,1,2,3],[1,2,7,9],[2,1,5,2]])
m,n=x.shape
x1=x[:,0].repeat(n-1)[:,None]
x2=x[:,1:].reshape(-1,1)
np.hstack([x1,x2])
制造

array([[0, 1],
       [0, 2],
       [0, 3],
       [1, 2],
       [1, 7],
       [1, 9],
       [2, 1],
       [2, 5],
       [2, 2]])

可能还有其他方法可以进行这种重排。结果将以某种方式复制原始数据。我的猜测是,只要您使用reshaperepeat等编译函数,时间差异就不会很大。

答案 2 :(得分:1)

假设numpy数组是

arr = np.array([[0, 1, 2, 3],
                [1, 2, 7, 9],
                [2, 1, 5, 2]])

您可以将对数组作为

import itertools
m, n = arr.shape
new_arr = np.array([x for i in range(m) 
                    for x in itertools.product(a[i, 0 : 1], a[i, 1 : n])])

输出为

array([[0, 1],
       [0, 2],
       [0, 3],
       [1, 2],
       [1, 7],
       [1, 9],
       [2, 1],
       [2, 5],
       [2, 2]])