python - Numpy:3D boolean 索引数组会发生什么

标签 python arrays numpy boolean

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

我有一个 4D 数组和一个用于前三个轴的 boolean 索引数组';索引的输出是扁平化的,至少在索引轴上是这样,所以它是一个“元组列表”(但以数组形式)。

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

<小时/>

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

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

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

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

这可能是完成任务的一种优雅且快速的方法(目标是了解一个平面中的每个站点与另一个平面中的哪些站点相邻 - 因此它们的坐标是已知的,但我想要它们的 ID)。

那么,numpy 内部是否有任何魔法来获取索引数组?或者采用 for-loop 也会同样快吗?;)(不,我通过尝试发现,这要快得多,但为什么......)

<小时/>

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

import numpy as np
Seitenlaenge = 4
kArray = np.zeros((Seitenlaenge, Seitenlaenge, Seitenlaenge, 3)) # 4D-Array, hier soll dann an der Stelle [x, y, z, :] der Vektor (x, y, z) stehen
kArray[:, :, :, 2] = np.arange(Seitenlaenge).reshape((1, 1, Seitenlaenge)).repeat(Seitenlaenge, axis = 0).repeat(Seitenlaenge, axis = 1)
kArray[:, :, :, 1] = np.arange(Seitenlaenge).reshape((1, Seitenlaenge, 1)).repeat(Seitenlaenge, axis = 0).repeat(Seitenlaenge, axis = 2)
kArray[:, :, :, 0] = np.arange(Seitenlaenge).reshape((Seitenlaenge, 1, 1)).repeat(Seitenlaenge, axis = 1).repeat(Seitenlaenge, axis = 2)
# Die Gitterpunkte waehlen die zu A und B gehoeren:

print kArray

Summe = 5 # Seitenlaenge des Dreiecks, das aus dem 1.Oktanten geschnitten wuerde, wenn der Wuerfel nicht kleiner waere
ObA = kArray.sum(axis=-1) == Summe-1 # 3D-boolean Array
ObB = kArray.sum(axis=-1) == Summe-2

print ObA

kA, kB = kArray[ObA], kArray[ObB] # Es bleiben 2D-Arrays: Listen von Koordina-
# tentripeln, in der Form (x, y, z)

print kA

如果您想看到蜂窝格子,请随后执行以下操作:

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 在索引方面非常聪明。它将展平您的 boolean 数组,计算 nnz、其中 True 的数量,分配形状为 (nnz, 3) 的输出数组,然后同时逐项迭代您的展平 boolean 数组,并以 3 个项目的跳跃方式迭代您的展平数组,即使用 3 个项目步幅。只要 boolean 数组具有 True,它就会将数组的下 3 项复制到输出数组,然后继续迭代。

所有这些都将在 C 中发生,因此它非常非常快,至少按照 Python 标准是这样。

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

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]

关于python - Numpy:3D boolean 索引数组会发生什么,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35970705/

相关文章:

python - 将数组四舍五入为另一个数组中给定的值

python - Numpy 切片多维错误产生意外结果

python - 在 conda 环境中使用 pip 是否仅在该 conda 环境中安装软件包?

php - 在一行中将数​​组插入数据库

c - 从 C 中的数组读取时出现错误字符/符号

Javascript 函数编程——接收复杂的参数

python - 如何对动态数据框进行OLS回归并估计斜率系数?

python - Django 过滤器,得到了一个意想不到的关键字参数

python - 使用 beautifulsoup 隐藏元素进行网页抓取

Python Unittest 抛出未捕获的 TypeError : __init__() takes 1 positional argument but 2 were given