Python 二维numpy数组的条件数学运算在一维上检查和在差维上执行不同的运算
我有一个2D numpy数组,其中第0列是设备的平移旋转,第1列是倾斜旋转。每一行都是不同的固定装置。我希望在每行上运行以下逻辑:Python 二维numpy数组的条件数学运算在一维上检查和在差维上执行不同的运算,python,arrays,numpy,multidimensional-array,vectorization,Python,Arrays,Numpy,Multidimensional Array,Vectorization,我有一个2D numpy数组,其中第0列是设备的平移旋转,第1列是倾斜旋转。每一行都是不同的固定装置。我希望在每行上运行以下逻辑: if(pantilt[0] > 90): pantilt[0] -=180 pantilt[1] *= -1 elif pantilt[0] < -90: pantilt[0] += 180 pantilt[1] *= -1 if(pantilt[0]>90): pantilt[0]=180 pantilt[1]*=-1
if(pantilt[0] > 90):
pantilt[0] -=180
pantilt[1] *= -1
elif pantilt[0] < -90:
pantilt[0] += 180
pantilt[1] *= -1
if(pantilt[0]>90):
pantilt[0]=180
pantilt[1]*=-1
elif pantilt[0]<-90:
pantilt[0]+=180
pantilt[1]*=-1
我理解1D上的基本条件操作,比如myarray[condition]=something。但我无法将其外推到更多维度 这个怎么样:
pantilt[:,0][pantilt[:,0]>90] -= 180
pantilt[:,1][pantilt[:,0]>90] *= -1
pantilt[:,0][pantilt[:,0]<-90] += 180
pantilt[:,1][pantilt[:,0]<-90] *= -1
pantilt[:,0][pantilt[:,0]>90]=180
pantilt[:,1][pantilt[:,0]>90]*=-1
pantilt[:,0][pantilt[:,0]我将计算一个掩码或布尔索引,并对每列使用if:
构造一个示例数组:
pantilt=np.column_stack([np.linspace(-180,180,11),np.linspace(0,90,11)])
I = pantilt[:,0]>90
# J = pantilt[:,0]<-90
pantilt[I,0] -= 180
pantilt[I,1] *= -1
I = pantilt[:,0]<-90 # could use J instead
pantilt[I,0] += 180
pantilt[I,1] *= -1
之后:
array([[ 0., -0.],
[ 36., -9.],
[ 72., -18.],
[-72., 27.],
[-36., 36.],
[ 0., 45.],
[ 36., 54.],
[ 72., 63.],
[-72., -72.],
[-36., -81.],
[ 0., -90.]])
如果列是独立的1d数组,这也同样有效。受此启发,可以分三步使用,而不是像其他两个解决方案中建议的那样分四步使用,如下所示-
import numpy as np
# Get mask correspindig to IF conditional statements in original code
mask_lt = pantilt[:,0]<-90
mask_gt = pantilt[:,0]>90
# Edit the first column as per the statements in original code
pantilt[:,0][mask_gt] -= 180
pantilt[:,0][mask_lt] += 180
# Edit the second column as per the statements in original code
pantilt[ mask_lt | mask_gt,1] *= -1
哇,这看起来比我想象的要简单得多!我没有想到要做两次检查。虽然我认为索引应该交换,而且要复杂一点?在我编写的简单代码(即内核)中,我的pantilt[0]是pan,pantilt[1]是tilt。当向量化到表pantilt_数组[0]中时将返回第一个pantilt条目,而不是第一列?同样,在执行检查时,它不应该是pantilt_数组[:,0]>90吗?是的,你说得对,我已经编辑了我的答案(实际上我不习惯直接使用numpy数组;我通常使用pandas以便列具有名称)事实上,我认为这也行不通!因为一旦覆盖第一列,第二个条件就失败了!所以你需要最后一个条件。而且我不理解[,][]语法。在[]中使用逗号不是与[][]相同吗?在[]中使用逗号以及其他[]是什么意思?我认为没关系:[pantilt[:,0]>90]
是一个索引器,即一个布尔数组,它选择条件为真的行。因此只更新这些行。而[:,0]
是一个列切片器,因此它返回整个第一列。
import numpy as np
# Get mask correspindig to IF conditional statements in original code
mask_lt = pantilt[:,0]<-90
mask_gt = pantilt[:,0]>90
# Edit the first column as per the statements in original code
pantilt[:,0][mask_gt] -= 180
pantilt[:,0][mask_lt] += 180
# Edit the second column as per the statements in original code
pantilt[ mask_lt | mask_gt,1] *= -1
In [530]: num_samples = 10000
...: org = np.random.randint(-180,180,(num_samples,2))
...:
In [531]: pantilt = org.copy()
In [532]: %timeit hpaulj_mask4(pantilt)
10000 loops, best of 3: 27.7 µs per loop
In [533]: pantilt = org.copy()
In [534]: %timeit maxymoo_mask4(pantilt)
10000 loops, best of 3: 33.7 µs per loop
In [535]: pantilt = org.copy()
In [536]: %timeit mask3(pantilt) # three-step masking approach from this solution
10000 loops, best of 3: 22.1 µs per loop