Python Numpy:3D布尔索引数组会发生什么

Python Numpy:3D布尔索引数组会发生什么,python,arrays,numpy,boolean,Python,Arrays,Numpy,Boolean,通常,numpy数组比列表操作或循环快得多,但在这种情况下也是如此: 对于前三个轴',我有一个4D数组和一个布尔索引数组;索引的输出是平坦的,至少在索引轴上是平坦的,因此它是一个“元组列表”(但以数组形式) 由于规则结构被破坏,我假设这比规则网格的索引(即独立索引每个轴)要慢得多?也许numpy在内部真的会计算元组列表,然后将其转换为数组 为什么我要问:我想枚举输出,以便能够计算任何元组(如果它在列表中)的位置。我试图了解哪种方法可能是快速和优雅的 我的背景: 我有一个整数坐标数组,一个网格-

通常,
numpy
数组比列表操作或循环快得多,但在这种情况下也是如此:

对于前三个轴',我有一个4D数组和一个布尔索引数组;索引的输出是平坦的,至少在索引轴上是平坦的,因此它是一个“元组列表”(但以数组形式)

由于规则结构被破坏,我假设这比规则网格的索引(即独立索引每个轴)要慢得多?也许numpy在内部真的会计算元组列表,然后将其转换为数组


为什么我要问:我想枚举输出,以便能够计算任何元组(如果它在列表中)的位置。我试图了解哪种方法可能是快速和优雅的

我的背景: 我有一个整数坐标数组,一个网格-所以逻辑上我有一个3元组的3D数组,但对于程序来说它是一个4D数组

我想得到坐标和等于常数的所有点,这是从我的立方体中切出一个平面(最后,我取两个相邻的平面,这给了我一个蜂窝状晶格——如果你喜欢数学的话,这非常漂亮:)

所以最后一个轴上的值就是前三个轴的指数。如果我不仅有一个
True
False
的索引数组,而且还分配了一个id而不是每个
True
,那么我就可以轻松地读出每个元组的id

这可能是完成任务的一种优雅而快速的方法(目标是知道其中一个平面上的每个站点,另一个的哪个站点相邻——因此它们的坐标是已知的,但我需要它们的id)

那么,numpy内部是否有任何魔法来获取索引数组?或者同样地,对循环执行
会很快吗(不,我试着看,这要快得多,但为什么…)


一些代码(德语注释,抱歉)

如果你想看到蜂巢状格子,然后再做:

import matplotlib.pyplot as plt

nx = np.array([-1, 1, 0])*2**-0.5
ny = np.array([-1, -1, 2])*6**-0.5
def Projektion(ListeTripel):
    return dot(ListeTripel, nx), dot(ListeTripel, ny)

xA, yA = Projektion(kA)
xB, yB = Projektion(kB)

plt.plot(xA.flatten(), yA.flatten(), 'o', c='r', ms=8, mew=0)
plt.plot(xB.flatten(), yB.flatten(), 'o', c='b', ms=8, mew=0)

plt.show()

Numpy在索引方面非常聪明。它将展平您的布尔数组,计算
nnz
,其中
True
s的数量,分配一个shape
(nnz,3)
的输出数组,然后逐项同时迭代展平的布尔数组,并以3项跳跃的方式(即以3项步幅)迭代展平的数组。只要布尔数组有一个
True
值,它就会将接下来的3个数组项复制到输出数组中,然后继续迭代

所有这些都将在C语言中实现,因此它非常非常快,至少按照Python标准是如此

顺便说一下,与您的问题有些无关,但请使用:


发布一些示例数据?这很有意义!:)谢谢你的解释,也谢谢你对广播的提示,当然这看起来更整洁了。我已经看到这样的数组带有
None
,但我认为“显式优于隐式”;-)-我会试着去读和理解它,谢谢。我认为最后一个1应该是2。另外,TIL约为
np.intp
,相当于
size\u t
import matplotlib.pyplot as plt

nx = np.array([-1, 1, 0])*2**-0.5
ny = np.array([-1, -1, 2])*6**-0.5
def Projektion(ListeTripel):
    return dot(ListeTripel, nx), dot(ListeTripel, ny)

xA, yA = Projektion(kA)
xB, yB = Projektion(kB)

plt.plot(xA.flatten(), yA.flatten(), 'o', c='r', ms=8, mew=0)
plt.plot(xB.flatten(), yB.flatten(), 'o', c='b', ms=8, mew=0)

plt.show()
length = 4
indices = np.arange(length)
k_array = np.empty((length,) * 3 + (3,), dtype=np.intp)
k_array[..., 0] = indices
k_array[... ,1] = indices[:, None]
k_array[... ,2] = indices[:, None, None]