在numpy中的3维矩阵中插入未对齐元素 [英] Insertion of non aligned elements in 3-dimensional matrices in numpy

查看:115
本文介绍了在numpy中的3维矩阵中插入未对齐元素的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在使用 numpy 1.9 python 2.7.5 处理3维矩阵. 这是一个示例:

I'm working with 3-dimensional matrices using numpy 1.9 and python 2.7.5. Here is an example:

>>> 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.,  1.,  1.],
        [ 1.,  1.,  1.]]])

>>> B
array([[[-1., -1., -1.],
        [99., 100., 101.],
        [-1., -1., -1.],
        [-1., -1., -1.],
        [-1., -1., -1.]],

       [[-1., -1., -1.],
        [-1., -1., -1.],
        [102., 103., 104.],
        [-1., -1., -1.],
        [-1., -1., -1.]]])

>>> C
array([1, 2])

根据C,我想将B中的所有元素插入A中. 示例:c[0] = 1 => After A[0, 1, :] has to be inserted B[0, 1, :]

I'd like to insert in A all elements from B, according to C. Example: c[0] = 1 => After A[0, 1, :] has to be inserted B[0, 1, :]

这是预期结果的一个例子

Here is an example of the expected result

>>> D
array([[[1.,  1.,  1.],
        [1.,  1.,  1.],
        [99., 100., 101.],
        [1.,  1.,  1.],
        [1.,  1.,  1.],
        [1.,  1.,  1.]],

       [[1.,  1.,  1.],
        [1.,  1.,  1.],
        [1.,  1.,  1.],
        [102., 103., 104.]
        [1.,  1.,  1.],
        [1.,  1.,  1.]]])

我发现了这个stackoverflow问题除了解决方案仅适用于二维矩阵并且我正在使用3维之外,它与我的非常相似.

I found this stackoverflow question that is really similar to mine except that the solution are only for 2-dimensional matrix and I'm working with 3-dimensional.

这是我的解决方法,但结果不正确:

Here is my solution but I get incorrect results:

C2 = np.repeat(C, 3)
r1 = np.repeat(np.arange(A.shape[0]), 3)
r2 = np.tile(np.arange(3), A.shape[0])
index_map = np.ravel_multi_index((r1, C2, r2), A.shape) + 1
np.insert(A.ravel(), index_map, B.ravel()[index_map]).reshape(A.shape[0], A.shape[1] + 1, A.shape[2])

这是使用for循环的正确但缓慢的解决方案:

Here is a correct, but slow, solution using a for loop:

A_2 = np.zeros((A.shape[0], A.shape[1] + 1, A.shape[2]))
for j in xrange(np.size(C, 0)):
  i = C[j]
  A_2[j, :, :] = np.concatenate((A[j, 0:i + 1, :], [B[j, i, :]], A[j, i + 1:, :]))

有什么主意吗?

谢谢!

推荐答案

您的代码存在的问题是,当您需要插入多个 元素顺序排列,则需要将它们插入相同位置. 比较:

The problem with your code is that when you need to insert several elements sequentially, you need to insert them at the same position. Compare:

In [139]: x = np.ones(5); x
Out[139]: array([ 1.,  1.,  1.,  1.,  1.])

In [140]: np.insert(x, [1,2,3], 100)
Out[140]: array([   1.,  100.,    1.,  100.,    1.,  100.,    1.,    1.])

In [141]: np.insert(x, [1,1,1], 100)
Out[141]: array([   1.,  100.,  100.,  100.,    1.,    1.,    1.,    1.])

编辑:原始答案包括完整的整理/整形 返回,但是在3d模式下,您需要多加注意才能正确执行操作.有一个 考虑到np.insertnp.take接受轴"参数,并允许多值插入. 这仍然需要进行一些重塑,但是并不能求助于 选择另外,请注意np.insertmi+1参数要插入 之后,而不是所选行之前:

The original answer included full unravelling/reshaping back, but in 3d you need a lot of care to do it right. There's an easier solution that takes into account the fact that np.insert and np.take accept "axis" parameter and allow multi-value insertion. That still requires some reshaping, but it doesn't resort to np.choose. Also, note the mi+1 argument to np.insert to insert after, not before the chosen rows:

In [50]: mi = np.ravel_multi_index([np.arange(A.shape[0]), C], A.shape[:2]); mi
Out[50]: array([1, 7])

In [51]: bvals = np.take(B.reshape(-1, B.shape[-1]), mi, axis=0); bvals
Out[51]: 
array([[  99.,  100.,  101.],
       [ 102.,  103.,  104.]])

In [52]: result = (np.insert(A.reshape(-1, A.shape[2]), mi + 1, bvals, axis=0)
                   .reshape(A.shape[0], -1, A.shape[2])); result
Out[52]: 
array([[[   1.,    1.,    1.],
        [   1.,    1.,    1.],
        [  99.,  100.,  101.],
        [   1.,    1.,    1.],
        [   1.,    1.,    1.],
        [   1.,    1.,    1.]],

       [[   1.,    1.,    1.],
        [   1.,    1.,    1.],
        [   1.,    1.,    1.],
        [ 102.,  103.,  104.],
        [   1.,    1.,    1.],
        [   1.,    1.,    1.]]])

这是原始答案:

In [18]: ixs = np.repeat(np.array([np.arange(A.shape[0]),
                                    C+1,
                                    np.zeros(A.shape[0], dtype=np.int_)]),
                          A.shape[2], axis=1); ixs
   ....: 
Out[18]: 
array([[0, 0, 0, 1, 1, 1],
       [2, 2, 2, 3, 3, 3],
       [0, 0, 0, 0, 0, 0]])

In [19]: mi = np.ravel_multi_index(ixs, A.shape); mi
Out[19]: array([ 6,  6,  6, 24, 24, 24])

In [20]: result = (np.insert(A.ravel(), mi, bvals)
                    .reshape(A.shape[0], A.shape[1] +1, A.shape[2])); result
   ....: 
Out[20]: 
array([[[   1.,    1.,    1.],
        [   1.,    1.,    1.],
        [  99.,  100.,  101.],
        [   1.,    1.,    1.],
        [   1.,    1.,    1.],
        [   1.,    1.,    1.]],

       [[   1.,    1.,    1.],
        [   1.,    1.,    1.],
        [   1.,    1.,    1.],
        [ 102.,  103.,  104.],
        [   1.,    1.,    1.],
        [   1.,    1.,    1.]]])

In [21]: result = (np.insert(A.ravel(), mi, bvals)
                    .reshape(A.shape[0], A.shape[1] +1, A.shape[2])); result
   ....: 
Out[21]: 
array([[[   1.,    1.,    1.],
        [   1.,    1.,    1.],
        [  99.,  100.,  101.],
        [   1.,    1.,    1.],
        [   1.,    1.,    1.],
        [   1.,    1.,    1.]],

       [[   1.,    1.,    1.],
        [   1.,    1.,    1.],
        [   1.,    1.,    1.],
        [ 102.,  103.,  104.],
        [   1.,    1.,    1.],
        [   1.,    1.,    1.]]])

这篇关于在numpy中的3维矩阵中插入未对齐元素的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆