简体   繁体   English

组合两个不同维的numpy数组

[英]Combining two numpy arrays of different dimensions

As I read through numpy tutorials, I give myself challenges to build my understanding. 当我阅读numpy教程时,我会给自己挑战以建立自己的理解。 I was reading through tutorialpoint.com's numpy resource when I saw in the last example that their end-product modified array was not really an array. 当我在上一个示例中看到他们的最终产品修改过的数组不是真正的数组时,我正在阅读tutorialpoint.com的numpy资源。

Bottom of page, Broadcasting Iteration example: https://www.tutorialspoint.com/numpy/numpy_iterating_over_array.htm 页面底部,广播迭代示例: https : //www.tutorialspoint.com/numpy/numpy_iterating_over_array.htm

So I decided it would be a nice challenge to try and create the same endproduct as an array. 因此,我认为尝试创建与数组相同的最终产品将是一个不错的挑战。 I succeeded but I was not able to use np.nditer nor was I able to utilize broadcasting although I'm sure there must be a way to utilize either/both. 我成功了,但是我无法使用np.nditer,也无法利用广播,尽管我确信必须有一种利用两者之一的方法。

Here is my code: 这是我的代码:

a = np.arange(0,60,5) 
a = a.reshape(12,1)
b = np.arange(1,5)
arr = np.zeros((12,2))

counter = 0
for i in range(arr.shape[0]):
    if counter < 4:
        arr[i,:] = np.array([a[i],b[counter]])
        counter += 1
    else:
        counter = 0
        arr[i,:] = np.array([a[i],b[counter]])

print arr

How can I do this more efficiently? 我怎样才能更有效地做到这一点?

I haven't seen that particular nditer tutorial before. 我以前没有看过特定的nditer教程。
https://docs.scipy.org/doc/numpy-1.13.0/reference/arrays.nditer.html https://docs.scipy.org/doc/numpy-1.13.0/reference/arrays.nditer.html

is the one I've used. 是我用过的那个 And I keep telling people, nditer , with this Python interface, is not efficient. 而且我一直在告诉人们nditer这个Python界面效率不高。 This page is most useful as stepping stone to using nditer in C code, as illustrated in the last cython example. 如最后一个cython示例所示,此页面对于在C代码中使用nditer跳板最有用。

There aren't many numpy functions that use np.nditer (in Python code). 使用np.nditer numpy函数并不多(在Python代码中)。 np.ndindex is one of the few. np.ndindex是少数几个。 It's worth reading its code. 值得阅读其代码。 np.einsum uses this iterator, but in compiled code. np.einsum使用此迭代器,但使用已编译的代码。

I'll take time later to read and comment on the example in question. 稍后,我将花一些时间阅读并评论所涉及的示例。 Learning to use broadcasting well is more important than using nditer . 学习好用广播比使用nditer更重要。

In [212]: a=np.arange(0,60,5).reshape(3,4)
In [213]: a
Out[213]: 
array([[ 0,  5, 10, 15],
       [20, 25, 30, 35],
       [40, 45, 50, 55]])
In [214]: b=np.arange(1,5)
In [215]: b
Out[215]: array([1, 2, 3, 4])

In [225]: for x,y in np.nditer([a,b]):
     ...:     print("%d:%d"%(x,y), end=' ')
     ...: print()
0:1 5:2 10:3 15:4 20:1 25:2 30:3 35:4 40:1 45:2 50:3 55:4 

Equivalent plain Python iteration: 等效的普通Python迭代:

In [231]: for row in a:
     ...:     for x,y in zip(row,b):
     ...:         print("%d:%d"%(x,y), end=' ')
     ...: print()
     ...: 
0:1 5:2 10:3 15:4 20:1 25:2 30:3 35:4 40:1 45:2 50:3 55:4 

np.broadcast will broadcast the (3,4) array with (4,): np.broadcast将使用(4,)广播(3,4)数组:

In [234]: np.broadcast(a,b)
Out[234]: <numpy.broadcast at 0x9c2a7f8>
In [235]: list(_)
Out[235]: 
[(0, 1),
 (5, 2),
 (10, 3),
 (15, 4),
 (20, 1),
 (25, 2),
 (30, 3),
 (35, 4),
 (40, 1),
 (45, 2),
 (50, 3),
 (55, 4)]

Use np.array(list(np.broadcast(a,b))) to make a (12,2) array. 使用np.array(list(np.broadcast(a,b)))制作(12,2)数组。

Or with the same print: 或使用相同的打印:

In [237]: for x,y in np.broadcast(a,b):
     ...:     print("%d:%d"%(x,y), end=' ')
     ...: print()
     ...: 
0:1 5:2 10:3 15:4 20:1 25:2 30:3 35:4 40:1 45:2 50:3 55:4

Your iteration: 您的迭代:

In [251]: arr = np.zeros((12,2),dtype=int)
     ...: counter = 0
     ...: for i in range(arr.shape[0]):
     ...:     if counter < 4:
     ...:         arr[i,:] = np.array([a.flat[i],b[counter]])
     ...:         counter += 1
     ...:     else:
     ...:         counter = 0
     ...:         arr[i,:] = np.array([a.flat[i],b[counter]])
     ...:         
In [252]: arr
Out[252]: 
array([[ 0,  1],
       [ 5,  2],
       [10,  3],
       [15,  4],
       [20,  1],
       [25,  1],
       [30,  2],
       [35,  3],
       [40,  4],
       [45,  1],
       [50,  1],
       [55,  2]])

Oops, looks like something off, if you expect the second column to be a repeated b . 糟糕,如果您希望第二列是重复的b ,则看起来有些不对劲。

There are many ways of combining a and b into this kind of array. 有很多方法可以将ab组合到这种数组中。

This turns the 2d a into a 1d; 这会将2d a变成1d; replicates b with tile , and joins them with stack ( column_stack would have worked as well): tile复制b ,然后将它们与stack连接( column_stack也可以使用):

In [264]: np.stack((a.flat, np.tile(b,3)),1)
Out[264]: 
array([[ 0,  1],
       [ 5,  2],
       [10,  3],
       [15,  4],
       [20,  1],
       [25,  2],
       [30,  3],
       [35,  4],
       [40,  1],
       [45,  2],
       [50,  3],
       [55,  4]])

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

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