Numpy:3Dboolean索引数组会发生什么

2024-10-01 05:06:11 发布

您现在位置:Python中文网/ 问答频道 /正文

通常,numpy数组比列表操作或循环快得多,但在这种情况下呢?公司名称:

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

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


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

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

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

所以最后一个轴上的值就是前三个轴的指数。如果我不仅有一个TrueFalse的索引数组,而且还分配了一个id而不是每个{},那么我就可以很容易地读取每个元组的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

如果你想看蜂巢状的格子,那就接着做:

^{pr2}$

Tags: numpyid列表np数组平面元组repeat
1条回答
网友
1楼 · 发布于 2024-10-01 05:06:11

Numpy在索引方面相当聪明。它将展平您的布尔数组,计算nnz,其中的True个数,分配一个形状为(nnz, 3)的输出数组,然后逐项在平坦的布尔数组上同时迭代,并以3个项目的跳跃(即3个项目步幅)对扁平数组进行迭代。只要布尔数组有一个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]

相关问题 更多 >