没有对齐的元素Efficent插入一个numpy的阵列 [英] Efficent insertion of not aligned elements in a numpy array
问题描述
我使用numpy的 1.9 在一组阵列的工作。假设我有类似的东西,我有两个二维数组 A
和 B
和一维数组<$ C $ ç> C ,这看起来像:
&GT;&GT;&GT;一个
阵列([1,1,1,1,1]
[1,1,1,1,1]
[1,1,1,1,1]
[1,1,1,1,1]
[1.,1。,1.,1.,1。]])
&GT;&GT;&GT;乙
阵列([[ - 。。1,-1,-1,-1,-1],
[-1,-1,-1,-1,-1],
[-1,-1,-1,-1,-1],
[-1,-1,-1,-1,-1],
[-1,-1,-1,-1,-1]])
&GT;&GT;&GT; C
阵列([1,3,2,4,0])
我的目标是从B A的所有元素插入,按C.更具体地讲,如果C位置0有一个1,B [0,1]应该是[0,1]。后插入p>
下面是预期的结果是:
阵列([1,1,-1,1,1,1],
[1,1,1,1,-1,1],
[1,1,1,-1,1,1],
[1,1,1,1,1,-1],
[1,-1,1,1,1,1]])
我想实现它这样的,但它不是非常快:
对我的xrange(尺寸(C,0)):
J = C [I]
A [我:] = numpy.insert(A [I],J,B [I,J])
有一种方法,使其更快? (跟单操作numpy的做到这一点,像面具或类似的东西)
如何讨厌单行?
首先,数据;该阵列具有相同的形状是你的,但我已经用整数使例子更易于阅读。
在[81]:一
出[81]:
阵列([0,1,2,3,4],
[5,6,7,8,9],
[10,11,12,13,14],
[15,16,17,18,19],
[20,21,22,23,24])在[82]:乙
出[82]:
阵列([0,100,200,300,400],
[500,600,700,800,900],
[1000,1100,1200,1300,1400],
[1500,1600,1700,1800,1900]
[2000,2100,2200,2300,2400])在[83]:C
出[83]:阵列([1,3,2,4,0])
而这里的肮脏一行代码:
在[84]:np.insert(A.ravel(),np.ravel_multi_index((范围(A.shape [0]),C),A.shape)+ 1,B [范围(B.shape [0]),C])。重塑(A.shape [0],A.shape [1] +1)
出[84]:
阵列([0,1,100,2,3,4],
[5,6,7,8,800 9]
[10,11,12,1200,13,14],
[15,16,17,18,19,1900]
[20,2000,21,22,23,24])
这里是破旧的版本:
A.ravel()
平坦 A
成一维数组,我会打电话给˚F
:
在[87]:F = A.ravel()在[88]:F
出[88]:
阵列([0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,
17,18,19,20,21,22,23,24])
(编辑:原来这第一步 - 展平 A
- 是不是必要的,因为在@hpaulj他的回答中指出,。 np.insert
将平由默认的阵列。)
np.ravel_multi_index
用于所期望的2-D位置到索引转换成扁平阵列。在 + 1
末,因为要插入的元素的是必要的后的在 C中列出该指数
:
在[89]:insert_indices = np.ravel_multi_index((范围(A.shape [0]),C),A.shape)+ 1在[90]:insert_indices
出[90]:阵列([2,9,13,20,21])
B [范围(B.shape [0]),C]
拉所需的值了 B的
在[91]:值= B [范围(B.shape [0]),C]在[92]:值
出[92]:阵列([100,800,1200,1900,2000)
np.insert
执行实际插入并创建一个新的数组:
在[93]:np.insert(F,insert_indices,价值观)
出[93]:
阵列([0,1,100,2,3,4,5,6,7,8,800,
9,10,11,12,1200,13,14,15,16,17,18,
19,1900,20,2000,21,22,23,24])
现在只是重塑,要得到最终的结果是:
在[94]:np.insert(F,insert_indices,价值观).reshape(A.shape [0],A.shape [1] +1)
出[94]:
阵列([0,1,100,2,3,4],
[5,6,7,8,800 9]
[10,11,12,1200,13,14],
[15,16,17,18,19,1900]
[20,2000,21,22,23,24])
I'm using numpy 1.9 to work on a set of arrays. Assuming I have something like that I have two 2d arrays A
and B
and a 1-d array C
, that looks like that:
>>> A
array([[ 1., 1., 1., 1., 1.],
[ 1., 1., 1., 1., 1.],
[ 1., 1., 1., 1., 1.],
[ 1., 1., 1., 1., 1.],
[ 1., 1., 1., 1., 1.]])
>>> B
array([[-1., -1., -1., -1., -1.],
[-1., -1., -1., -1., -1.],
[-1., -1., -1., -1., -1.],
[-1., -1., -1., -1., -1.],
[-1., -1., -1., -1., -1.]])
>>> C
array([1, 3, 2, 4, 0])
My goal is to insert in A all elements from B, according to C. More specifically, if C at position 0 has a 1, B[0, 1] should be inserted after A[0, 1].
Here's the expected result:
array([[ 1, 1, -1, 1, 1, 1],
[ 1, 1, 1, 1, -1, 1],
[ 1, 1, 1, -1, 1, 1],
[ 1, 1, 1, 1, 1, -1],
[ 1, -1, 1, 1, 1, 1]])
I tried to implement it like that, but it's not very fast:
for i in xrange(size(C, 0)):
j = C[i]
A[i, :] = numpy.insert(A[i], j, B[i, j])
There is a way to make it faster? (do it with a single numpy operation, like masks or something like that)
How about a nasty one-liner?
First, the data; the arrays have the same shape as yours, but I've used integers to make the example easier to read.
In [81]: A
Out[81]:
array([[ 0, 1, 2, 3, 4],
[ 5, 6, 7, 8, 9],
[10, 11, 12, 13, 14],
[15, 16, 17, 18, 19],
[20, 21, 22, 23, 24]])
In [82]: B
Out[82]:
array([[ 0, 100, 200, 300, 400],
[ 500, 600, 700, 800, 900],
[1000, 1100, 1200, 1300, 1400],
[1500, 1600, 1700, 1800, 1900],
[2000, 2100, 2200, 2300, 2400]])
In [83]: C
Out[83]: array([1, 3, 2, 4, 0])
And here's the nasty one-liner:
In [84]: np.insert(A.ravel(), np.ravel_multi_index((range(A.shape[0]), C), A.shape) + 1, B[range(B.shape[0]), C]).reshape(A.shape[0], A.shape[1]+1)
Out[84]:
array([[ 0, 1, 100, 2, 3, 4],
[ 5, 6, 7, 8, 800, 9],
[ 10, 11, 12, 1200, 13, 14],
[ 15, 16, 17, 18, 19, 1900],
[ 20, 2000, 21, 22, 23, 24]])
Here's the broken-down version:
A.ravel()
flattens A
into a 1-d array, which I'll call F
:
In [87]: F = A.ravel()
In [88]: F
Out[88]:
array([ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16,
17, 18, 19, 20, 21, 22, 23, 24])
(EDIT: It turns out this first step--flattening A
--is not necessary. As @hpaulj points out in his answer, np.insert
will flatten the array by default.)
np.ravel_multi_index
is used to convert the desired 2-d positions into the indices into the flattened array. The + 1
at the end is necessary because you want to insert the elements after the index given in C
:
In [89]: insert_indices = np.ravel_multi_index((range(A.shape[0]), C), A.shape) + 1
In [90]: insert_indices
Out[90]: array([ 2, 9, 13, 20, 21])
B[range(B.shape[0]), C]
pulls the desired values out of B
:
In [91]: values = B[range(B.shape[0]), C]
In [92]: values
Out[92]: array([ 100, 800, 1200, 1900, 2000])
np.insert
does the actual insertion and creates a new array:
In [93]: np.insert(F, insert_indices, values)
Out[93]:
array([ 0, 1, 100, 2, 3, 4, 5, 6, 7, 8, 800,
9, 10, 11, 12, 1200, 13, 14, 15, 16, 17, 18,
19, 1900, 20, 2000, 21, 22, 23, 24])
Now just reshape that to get the final result:
In [94]: np.insert(F, insert_indices, values).reshape(A.shape[0], A.shape[1]+1)
Out[94]:
array([[ 0, 1, 100, 2, 3, 4],
[ 5, 6, 7, 8, 800, 9],
[ 10, 11, 12, 1200, 13, 14],
[ 15, 16, 17, 18, 19, 1900],
[ 20, 2000, 21, 22, 23, 24]])
这篇关于没有对齐的元素Efficent插入一个numpy的阵列的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!