如何在numpy中创建一个数组元组的3D数组,其中3D数组的每个元素都像np.where的输出?

时间:2016-03-11 18:27:37

标签: python arrays numpy

我有一个3D数组,每个轴的长度相同(~100),对应于3D空间中的位置。该数组的每个元素都有一个值(float64)。我正在尝试创建一个标识邻居的数组,其中这个新3D数组的每个元素都由一个数组元组组成,类似于np.where的输出,这样我就可以循环遍历3D数组的每个元素并对所有元素执行操作邻居。

我知道np.where 3D数组会输出一个3元组的数组,其中每个数组的长度是相同的,是满足给定条件的元素数。我尝试做类似的事情,但在我的情况下,我知道这些数组的长度是6,因为3D数组的每个元素都有6个直接邻居。我想将3D邻居数组的每个元素设置为3个长度为6的数组的元组。

我想做的是:

>>> 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.

是否可以将数组元素设置为数组元组?

1 个答案:

答案 0 :(得分:0)

要在NumPy数组的单元格中存储任意Python对象,请将dtype更改为object:此处,您需要更改

neighbors = np.zeros((100,100,100))

neighbors = np.zeros((100,100,100), dtype='O')

默认情况下np.zeros创建一个浮点dtype数组,这意味着数组的每个单元格都必须保存一个浮点值,因此出现错误信息:

ValueError: setting an array element with a sequence.

请注意,使用object dtype数组禁止NumPy使用快速数值方法 - 代码将比使用本机(例如浮点)dtype数组的等效NumPy代码慢。

例如,您可能最好创建一个浮点dtype 和shape (3,6,100,100,100)数组,其中第一个轴(长度为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)])

然后neighbors是一个带有原生NumPy dtype的数组:

In [32]: neighbors.dtype
Out[32]: dtype('int64')

In [33]: neighbors.shape
Out[33]: (3, 6, 100, 100, 100)

以下是与您的neighbors[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]])

以下是这些子阵列中的第二个,对应于您的neighbors[5,6,9][1]

In [37]: neighbors[1,:,5,6,9]
Out[37]: array([6, 6, 5, 7, 6, 6])

这是第二个子阵列中的第四个值,对应于您的neighbors[5,6,9][1][3]

In [38]: neighbors[1,3,5,6,9]
Out[38]: 7