简体   繁体   English

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

[英]How to create a 3D array of a tuple of arrays in numpy, where each element of the 3D array is like the output of np.where?

I have a 3D array where each axis is the same length (~100) and corresponds to a location in 3D space. 我有一个3D数组,其中每个轴的长度都相同(〜100),并且对应于3D空间中的位置。 Each element of this array has a value (float64). 该数组的每个元素都有一个值(float64)。 I am trying to create an array identifying neighbors where each element of this new 3D array consists of a tuple of arrays, similar to the output of np.where so that I can loop through each element of the 3D array and perform an operation on all the neighbors. 我正在尝试创建一个识别邻居的数组,该新3D数组的每个元素都由一个数组的元组组成,类似于np.where的输出,以便我可以遍历3D数组的每个元素并对所有元素执行操作邻居。

I know np.where for a 3D array would output a 3-tuple of arrays, where the length of each array is the same and is the number of elements satisfying the given condition. 我知道np.where对于3D数组将输出3个元组的数组,其中每个数组的长度是相同的,并且是满足给定条件的元素数。 I'm trying to do something similar, but in my case I know that the length of these arrays is 6, since each element of the 3D array has 6 immediate neighbors. 我正在尝试做类似的事情,但就我而言,我知道这些数组的长度为6,因为3D数组的每个元素都有6个直接邻居。 I want to set each element of the 3D neighbors array to be a tuple of 3 arrays of length 6. 我想将3D邻居数组的每个元素设置为3个长度为6的数组的元组。

What I would like to do is something like: 我想做的是这样的:

>>> 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]))

whereas what I actually get is the following error: 而我实际上得到的是以下错误:

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

Any way to set elements of an array as a tuple of arrays? 有什么办法将数组的元素设置为数组的元组?

To store arbitrary Python objects in the cells of a NumPy array, change the dtype to object : Here, you would need to change 要将任意Python对象存储在NumPy数组的单元格中,请将dtype更改为object :在这里,您需要更改

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

to

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

By default np.zeros creates an array of floating point dtype, which means every cell of the array must hold a floating point value, hence the error message: 默认情况下, np.zeros创建一个浮点np.zeros数组,这意味着该数组的每个单元格都必须包含一个浮点值,因此会出现错误消息:

ValueError: setting an array element with a sequence.

Beware that using arrays of object dtype inhibits NumPy from using fast numerical methods -- the code will be slower than equivalent NumPy code that uses arrays of native (eg floating point) dtype. 注意,使用object dtype的数组会阻止NumPy使用快速数值方法-该代码将比使用本机(例如浮点)dtype的等效NumPy代码慢。

For example, you might be better off creating an array of floating point dtype and shape (3,6,100,100,100) where the first axis (of length 3) allows you to select amongst the three subarrays, 例如,您最好创建一个浮点 (3,6,100,100,100)和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]))

and the second axis (of length 6) allows you to select amongst the 6 values in the subarray: 第二个轴(长度为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)])

Then neighbors is an array with a native NumPy dtype: 然后neighbors是一个具有本地NumPy dtype的数组:

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

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

Here are the three subarrays, corresponding to your neighbors[5,6,9] : 这是与您的neighbors[5,6,9]相对应的三个子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]])

Here is the second of these subarrays, corresponding to your neighbors[5,6,9][1] : 这是这些子neighbors[5,6,9][1]的第二个,对应于您的neighbors[5,6,9][1]

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

And here is the fourth value in the second subarray, corresponding to your neighbors[5,6,9][1][3] : 这是第二个子neighbors[5,6,9][1][3]的第四个值,对应于您的neighbors[5,6,9][1][3]

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM