Python 通过移位索引移位二维数组中的数据
我需要移动一个2D数组字段,也就是说,我有一个“先前的_数据”数组,我通过移动的索引访问该数组,以创建我的“新_数据”数组 我可以在一个非pythonic(和慢速)循环中完成这项工作,但非常感谢您在寻找pythonic(和更快)解决方案时提供帮助 非常感谢任何帮助和提示Python 通过移位索引移位二维数组中的数据,python,arrays,numpy,Python,Arrays,Numpy,我需要移动一个2D数组字段,也就是说,我有一个“先前的_数据”数组,我通过移动的索引访问该数组,以创建我的“新_数据”数组 我可以在一个非pythonic(和慢速)循环中完成这项工作,但非常感谢您在寻找pythonic(和更快)解决方案时提供帮助 非常感谢任何帮助和提示 import numpy as np import matplotlib.pyplot as plt from matplotlib import mpl def nonpythonic(): #this works,
import numpy as np
import matplotlib.pyplot as plt
from matplotlib import mpl
def nonpythonic():
#this works, but is slow (for large arrays)
new_data = np.zeros((ny,nx))
for j in xrange(ny):
for i in xrange(nx):
#go through each item, check if it is within the bounds
#and assign the data to the new_data array
i_new = ix[j,i]
j_new = iy[j,i]
if ((i_new>=0) and (i_new<nx) and (j_new>=0) and (j_new<ny)):
new_data[j,i]=previous_data[j_new,i_new]
ef, axar = plt.subplots(1,2)
im = axar[0].pcolor(previous_data, vmin=0,vmax=2)
ef.colorbar(im, ax=axar[0], shrink=0.9)
im = axar[1].pcolor(new_data, vmin=0,vmax=2)
ef.colorbar(im, ax=axar[1], shrink=0.9)
plt.show()
def pythonic():
#tried a few things here, but none are working
#-tried assigning NaNs to indices (ix,iy) which are out of bounds, but NaN's don't work for indices
#-tried masked arrays, but they also don't work as indices
#-tried boolean arrays, but ended in shape mismatches
#just as in the nonworking code below
ind_y_good = np.where(iy>=0) and np.where(iy<ny)
ind_x_good = np.where(ix>=0) and np.where(ix<nx)
new_data = np.zeros((ny,nx))
new_data[ind_y_good,ind_x_good] = previous_data[iy[ind_y_good],ix[ind_x_good]]
#some 2D array:
nx = 20
ny = 30
#array indices:
iy, ix = np.indices((ny,nx))
#modify indices (shift):
iy = iy + 1
ix = ix - 4
#create some out of range indices (which might happen in my real scenario)
iy[0,2:7] = -9999
ix[0:3,-1] = 6666
#some previous data which is the basis for the new_data:
previous_data = np.ones((ny,nx))
previous_data[2:8,10:20] = 2
nonpythonic()
pythonic()
将numpy导入为np
将matplotlib.pyplot作为plt导入
从matplotlib导入mpl
def nonpythonic():
#这可以工作,但速度很慢(对于大型阵列)
新数据=np.0((ny,nx))
对于X范围内的j(纽约):
对于x范围内的i(nx):
#检查每个项目,检查是否在范围内
#并将数据分配给新的_数据数组
i_new=ix[j,i]
j_new=iy[j,i]
如果((i_new>=0)和(i_new=0)和(j_new我实现了一个版本的pythonic
,它复制非pythonic
,并进行一些掩蔽和索引调整-请参见下文。顺便说一句,我认为“新”索引应该是与新数组对应的索引,而不是旧的,但我将其保留在现有函数中
要意识到的主要一点是,在你试图回答这个问题时,你的条件
ind_y_good = np.where(iy>=0) and np.where(iy<ny)
ind_x_good = np.where(ix>=0) and np.where(ix<nx)
非常感谢,这很有效!现在我看到了解决方案,它看起来非常明显和简单!太好了!用一双新的眼睛总是很容易
import numpy as np
import matplotlib.pyplot as plt
from matplotlib import mpl
def nonpythonic(previous_data, ix, iy, nx, ny):
#this works, but is slow (for large arrays)
new_data = np.zeros((ny,nx))
for j in xrange(ny):
for i in xrange(nx):
#go through each item, check if it is within the bounds
#and assign the data to the new_data array
i_new = ix[j,i]
j_new = iy[j,i]
if ((i_new>=0) and (i_new<nx) and (j_new>=0) and (j_new<ny)):
new_data[j,i]=previous_data[j_new,i_new]
return new_data
def pythonic(previous_data, ix, iy):
ny, nx = previous_data.shape
iy_old, ix_old = np.indices(previous_data.shape)
# note you must apply the same condition to both
# index arrays
valid = (iy >= 0) & (iy < ny) & (ix >= 0) & (ix < nx)
new_data = np.zeros((ny,nx))
new_data[iy_old[valid], ix_old[valid]] = previous_data[iy[valid], ix[valid]]
return new_data
def main():
#some 2D array:
nx = 20
ny = 30
#array indices:
iy, ix = np.indices((ny,nx))
#modify indices (shift):
iy = iy + 1
ix = ix - 4
#create some out of range indices (which might happen in my real scenario)
iy[0,2:7] = -9999
ix[0:3,-1] = 6666
#some previous data which is the basis for the new_data:
previous_data = np.ones((ny,nx))
previous_data[2:8,10:20] = 2
data_nonpythonic = nonpythonic(previous_data, ix, iy, nx, ny)
data_pythonic = pythonic(previous_data, ix, iy)
new_data = data_nonpythonic
ef, axar = plt.subplots(1,2)
im = axar[0].pcolor(previous_data, vmin=0,vmax=2)
ef.colorbar(im, ax=axar[0], shrink=0.9)
im = axar[1].pcolor(new_data, vmin=0,vmax=2)
ef.colorbar(im, ax=axar[1], shrink=0.9)
plt.show()
print(np.allclose(data_nonpythonic, data_pythonic))
if __name__ == "__main__":
main()