如何有效地重复具有偏移量的 2D numpy 数组?

问题描述

假设我有一个包含三列的 2D numpy 点数组,我想在 x 方向重复这些点,生成一个包含原始点集的新数组,以及一些“重复”点通过某个向量 在 x 方向上平移 (1,2,3,...,n) 次。

要清楚,假设我在原始数组中有 [0.1,2.0,5.0] 点,并且我想使用向量 '重复' 5 次,我将有以下内容在最终数组中:

new_array = [[0.1,5.0],[2.1,[4.1,[6.1,[8.1,[10.1,5.0]]

有没有办法使用内置的 numpy 矢量化来有效地做到这一点?

解决方法

import numpy as np

point = [0.1,2,5]
vector = [2,0]
n = 5

a = np.zeros((n,len(vector)))
a[1:] = vector
a = np.cumsum(a,axis=0) + point

a[1:] = vector 将创建数组

[[0. 0. 0.]
 [2. 0. 0.]
 [2. 0. 0.]
 [2. 0. 0.]
 [2. 0. 0.]]

这是您想要的每行差异。然后您将它们累计求和并将该点添加为偏移量。

,

已接受答案的变体:

In [33]: point = np.array([0.1,2.0,5.0])
In [34]: vector = np.array([2,0])
In [35]: np.arange(5)[:,None]*vector
Out[35]: 
array([[0,0],[2,[4,[6,[8,0]])
In [36]: np.arange(5)[:,None]*vector + point
Out[36]: 
array([[0.1,2.,5. ],[2.1,[4.1,[6.1,[8.1,5. ]])

您的评论提到了结构化数组。例如,如果 point 有 3 个字段,而您想修改第一个:

In [37]: arr = np.array([(0.1,5.0)],dtype='f,f,f')
In [38]: arr
Out[38]: array([(0.1,5.)],dtype=[('f0','<f4'),('f1',('f2','<f4')])
In [41]: arr = arr.repeat(5)
In [42]: arr
Out[42]: 
array([(0.1,5.),(0.1,'<f4')])
In [43]: arr['f0']
Out[43]: array([0.1,0.1,0.1],dtype=float32)
In [44]: arr['f0'] += np.arange(5)*2
In [45]: arr
Out[45]: 
array([(0.1,(2.1,(4.1,(6.1,(8.1,'<f4')])

您不能同时修改所有 3 个字段。数学不适用于跨领域。

,

由于已经给出的两个答案的提示,我自己的答案。我也有结构化数组的答案 - 如果有人感兴趣,我可以编辑这篇文章并将其添加到下方。

给定一个起始数组:array = np.array([[1,3],...,[10,9,8]]),一个向量:vector = np.array([1,3,5]) 和所需的重复次数:repeat = 5。您可以使用以下代码:

new_array = np.repeat(array,repeat)
vector_shifts = np.array([vector*index for index in range(0,repeat)])
vector_shifts = vector_shifts[np.newaxis,:]
vector_shifts = np.repeat(vector_shifts,array.shape[0],axis=0)

np.newaxis 创建一个额外的轴,它在重复时停止移动分组,这是标准的 np.repeat() 行为。例如 np.repeat(np.array([[1,4],5]],2) 给出一个输出:np.array([[1,[1,5],5]]

vector_shifts = vector_shifts.reshape(vector_shifts.shape[0]*vector_shifts.shape[1],3)

这会删除为 np.repeat() 添加的附加轴以按需要执行。最后,可以将向量移位添加到新数组中,以提供重复点的扩展数组。

new_array += vector_shift