Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/300.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/465.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python numpy中四维矩阵中非对齐元素的插入_Python_Arrays_Numpy_Matrix_Multidimensional Array - Fatal编程技术网

Python numpy中四维矩阵中非对齐元素的插入

Python numpy中四维矩阵中非对齐元素的插入,python,arrays,numpy,matrix,multidimensional-array,Python,Arrays,Numpy,Matrix,Multidimensional Array,我正在使用numpy1.9和python2.7.5处理四维矩阵 我正在使用3个numpy数组A,B,C(这是要组合的数组): 我想根据C在A中插入B中的所有元素 例如: c[0,0]=[1]=>必须在[0,0,1,:]之后插入B[0,0,1,:] c[0,1]=[1]=>必须在[0,1,1,:]之后插入B[0,1,1,:] c[1,0]=[1]=>必须在[1,0,1,:]之后插入B[1,0,1,:] c[1,1]=[1]=>A[1,1,1,:]之后必须插入B[1,1,1,:] 我问了同样的问

我正在使用numpy1.9python2.7.5处理四维矩阵

我正在使用3个numpy数组
A
B
C
(这是要组合的数组):

我想根据
C
A
中插入
B
中的所有元素
例如:

  • c[0,0]=[1]=>必须在[0,0,1,:]之后插入B[0,0,1,:]
  • c[0,1]=[1]=>必须在[0,1,1,:]之后插入B[0,1,1,:]
  • c[1,0]=[1]=>必须在[1,0,1,:]之后插入B[1,0,1,:]
  • c[1,1]=[1]=>A[1,1,1,:]之后必须插入B[1,1,1,:]
我问了同样的问题,但我不能得到同样的结果为4D阵列(我是相当新的numpy)

有什么想法吗

谢谢

救援:

>>> C = np.asarray(C)
>>> D = np.ones((2,2,5,3))
>>> idx = np.arange(len(C))
>>> D[idx, C[:, 0], C[:, 1]+1] = B[idx, C[:, 0], C[:, 1]]
>>> D
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.],
         [ 102.,  103.,  104.],
         [   1.,    1.,    1.]]],


       [[[   1.,    1.,    1.],
         [   1.,    1.,    1.],
         [  96.,   97.,   98.],
         [   1.,    1.,    1.],
         [   1.,    1.,    1.]],

        [[   1.,    1.,    1.],
         [   1.,    1.,    1.],
         [   1.,    1.,    1.],
         [   1.,    1.,    1.],
         [   1.,    1.,    1.]]]])

您可以将阵列重塑为3d,并使用上一个问题中的解决方案:

def fn_4d(A,B,C, fn):
    shape = list(A.shape)
    A = A.reshape(-1,A.shape[-2], A.shape[-1])
    B = B.reshape(-1,B.shape[-2], B.shape[-1])
    C = np.array(C).reshape(-1)
    A2 = fn(A,B,C)
    shape[-2] += 1
    A2 = A2.reshape(shape)
    return A2
如果你的迭代解是

def iter_3d(A,B,C):
    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:, :]))
    return A_2

fn_4d(A, B, C, iter_3d)
这种重塑非常普遍,适用于从原始3d尺寸到以上的任何尺寸-只要插入件处于
-2
尺寸

连接的另一种选择是:

  A_2[j,:,:] = np.insert(A[j,...], i+1, B[j,i,:], axis=0)
但深入到
insert
,可以看出它实际上是在做:

  A_2[j,:i+1,:] = A[j,:i+1,:]
  A_2[j,i+1,:] = B[j,i,:]
  A_2[j,i+2:,:] = A[j,i+1:,:]
这些备选方案的时间安排大致相同

一次插入多行的三维解决方案实际上使用布尔掩码索引:

def insert_3d2(A,B,C):
    mi = np.ravel_multi_index([np.arange(A.shape[0]), C], A.shape[:2])
    bvals = np.take(B.reshape(-1, B.shape[-1]), mi, axis=0)
    # result = np.insert(A.reshape(-1, A.shape[2]), mi + 1, bvals, axis=0)
    # which does:

    mi += np.arange(len(mi))
    A1 = A.reshape(-1, A.shape[2])
    shape = list(A1.shape)
    shape[0] += len(mi)
    A2 = np.empty(shape,dtype=A1.dtype)
    mask = np.ones(shape[0], dtype=bool)
    mask[mi] = False
    A2[mask,:] = A1
    A2[mi,:] = bvals

    A2 = A2.reshape(A.shape[0], -1, A.shape[2])
    return A2
也就是说,它构造一个布尔掩码来定义在新的空数组中放置
a
行的位置。显然,索引不连续块的速度优势很小

这里是对掩模方法的重写,没有任何展平。它始终比任何其他版本都快。我一直在
C
上进行迭代,因为这是查看该参数最清晰的方法。将枚举(C)循环替换为向量操作,类似于用于
mi
bvals
的向量操作,可以节省少量时间

def insert_3d3(A,B,C):
    # without flattening
    shape = list(A.shape)
    shape[1] += 1
    A2 = np.empty(shape, dtype=A.dtype)
    mask = np.ones(shape, dtype=bool)
    for j,i in enumerate(C):
        mask[j,i+1,:] = False
        A2[j,i+1,:] = B[j,i,:]
    A2[mask] = A.ravel()
    return A2

我想你误解了,我所指的矩阵是示例(现在我编辑我的问题是为了澄清它),我想在A中插入B中的所有元素,根据C,但A是一个通用矩阵,而不是一个一个矩阵。那么我恐怕你的问题是严重定义不清的。。。为了能够插入这些条目,您需要将
A
的形状扩展到第三维的
1
。在2D切片中,
A[0,1]
A[1,0]
这很好,因为我们有东西要插入。但是应该在片
A[0,0]
A[1,1]
中插入什么?对不起,你完全正确。现在我更正我的问题,在3D情况下,for循环解决方案有什么问题?当然你可以扩展它。当然它会工作,但是for循环比纯numpy解决方案慢得多,我需要一个尽可能快的解决方案。你用3d insert解决方案计时了吗?对于这些小样本阵列,速度较慢。您使用的阵列的大小。最重要的是,
C
中有多少术语?您了解3d insert解决方案吗?我对
numpy
并不陌生,但我还是需要一些时间来消化它。我用
(200200)
大小数组尝试了3d解决方案。您的迭代解决方案仍然快了3倍多。
def insert_3d3(A,B,C):
    # without flattening
    shape = list(A.shape)
    shape[1] += 1
    A2 = np.empty(shape, dtype=A.dtype)
    mask = np.ones(shape, dtype=bool)
    for j,i in enumerate(C):
        mask[j,i+1,:] = False
        A2[j,i+1,:] = B[j,i,:]
    A2[mask] = A.ravel()
    return A2