Python 如何在numpy中创建数组元组的3D数组,其中3D数组的每个元素都类似于np.where的输出?
我有一个3D数组,其中每个轴的长度相同(~100),对应于3D空间中的一个位置。此数组的每个元素都有一个值(float64)。我试图创建一个数组来标识邻居,其中这个新3D数组的每个元素都由数组元组组成,类似于np.where的输出,这样我就可以循环遍历3D数组的每个元素,并对所有邻居执行操作 我知道np。对于一个3D数组,其中会输出一个3元组的数组,其中每个数组的长度是相同的,并且是满足给定条件的元素数。我试图做一些类似的事情,但在我的例子中,我知道这些数组的长度是6,因为3D数组的每个元素都有6个直接邻居。我想将3D邻居数组的每个元素设置为3个长度为6的数组的元组 我想做的是:Python 如何在numpy中创建数组元组的3D数组,其中3D数组的每个元素都类似于np.where的输出?,python,arrays,numpy,Python,Arrays,Numpy,我有一个3D数组,其中每个轴的长度相同(~100),对应于3D空间中的一个位置。此数组的每个元素都有一个值(float64)。我试图创建一个数组来标识邻居,其中这个新3D数组的每个元素都由数组元组组成,类似于np.where的输出,这样我就可以循环遍历3D数组的每个元素,并对所有邻居执行操作 我知道np。对于一个3D数组,其中会输出一个3元组的数组,其中每个数组的长度是相同的,并且是满足给定条件的元素数。我试图做一些类似的事情,但在我的例子中,我知道这些数组的长度是6,因为3D数组的每个元素都有
>>> values = np.zeros((100,100,100))
>>> neighbors = np.zeros((100,100,100))
>>> for i in range(neighbors.shape[0]):
>>> for j in range(neighbors.shape[1]):
>>> for k in range(neighbors.shape[2]):
>>> neighbors[i,j,k] = (np.array([i-1,i+1,i,i,i,i]),np.array([j,j,j-1,j+1,j,j]),np.array([k,k,k,k,k-1,k+1]))
>>> neighbors[5,6,9]
(array([4,6,5,5,5,5]), array([6,6,5,7,6,6]), array([9,9,9,9,8,10]))
然而,我实际得到的是以下错误:
>>> values = np.zeros((100,100,100))
>>> neighbors = np.zeros((100,100,100))
>>> for i in range(neighbors.shape[0]):
>>> for j in range(neighbors.shape[1]):
>>> for k in range(neighbors.shape[2]):
>>> neighbors[i,j,k] = (np.array([i-1,i+1,i,i,i,i]),np.array([j,j,j-1,j+1,j,j]),np.array([k,k,k,k,k-1,k+1]))
ValueError: setting an array element with a sequence.
有没有办法将数组的元素设置为数组的元组?要在NumPy数组的单元格中存储任意Python对象,请将数据类型更改为
object
:在这里,您需要更改
neighbors = np.zeros((100,100,100))
到
默认情况下,np.zeros
创建一个浮点数据类型的数组,这意味着数组的每个单元格都必须包含一个浮点值,因此出现错误消息:
ValueError: setting an array element with a sequence.
请注意,使用
object
dtype数组会禁止NumPy使用快速数值方法——该代码将比使用本机(例如浮点)dtype数组的等效NumPy代码慢
例如,您最好创建一个浮点数据类型和形状的数组(3,610100100)
,其中第一个轴(长度为3)允许您在三个子数组中进行选择
(array([4,6,5,5,5,5]), array([6,6,5,7,6,6]), array([9,9,9,9,8,10]))
第二个轴(长度为6)允许您在子阵列中的6个值中进行选择:
import numpy as np
d, h, w = 100, 100, 100
I, J, K = np.mgrid[:d, :h, :w]
neighbors = np.array([(I-1,I+1,I,I,I,I), (J,J,J-1,J+1,J,J), (K,K,K,K,K-1,K+1)])
然后,邻居
是一个具有本机NumPy数据类型的数组:
In [32]: neighbors.dtype
Out[32]: dtype('int64')
In [33]: neighbors.shape
Out[33]: (3, 6, 100, 100, 100)
下面是三个子阵列,对应于您的邻居[5,6,9]
:
In [36]: neighbors[:,:,5,6,9]
Out[36]:
array([[ 4, 6, 5, 5, 5, 5],
[ 6, 6, 5, 7, 6, 6],
[ 9, 9, 9, 9, 8, 10]])
这是这些子阵列中的第二个子阵列,对应于您的邻居[5,6,9][1]
:
In [37]: neighbors[1,:,5,6,9]
Out[37]: array([6, 6, 5, 7, 6, 6])
这是第二个子数组中的第四个值,对应于您的邻居[5,6,9][1][3]
:
In [38]: neighbors[1,3,5,6,9]
Out[38]: 7
这还允许我使用奇特的索引对邻居的值执行操作吗?例如,
np.average(值[邻居[5,6,9]])
,这是我的最终目标。就性能而言,如果我只对每个元素本身的元组进行操作,我还会得到numpy的好处吗,因为我不会对整个Neights对象进行操作,而只是对数组元组中的元素进行操作?回答我自己的问题,是的,类似于np.average(值[Neights[5,6,9]])
在将Neights数据类型设置为object时起作用。
In [38]: neighbors[1,3,5,6,9]
Out[38]: 7