通过组合索引和表达式掩码来切割numpy数组

时间:2014-12-12 15:58:01

标签: python arrays python-2.7 numpy slice

我要分析一个(~20k顶点)3D四边形网格,因此需要根据某些标准将其分解为子网格。

鉴于

  • 顶点数组(准确地说是N 3元组的顶点坐标)
  • 四面引用那些顶点的序列号
  • 顶点的反向映射到它们所属的(4)面的序号

分解的基本标准有两种:

  • 作为面部或顶点索引的序列
  • 或表达式

需要编写这些基本标准,以产生我分析所需的集合。

从表达式标准中获取索引列表很容易;这只是

numpy.where(mask)

我不知道如何从给定的索引列表中有效地获取掩码;我的SSCCE下面的蛮力方法(在(A))

boolean_mask_from_selected_face_indices = [
    i in selected_face_indices for i in range(faces.shape[0])
]

工作,但看起来效率低下。

因此,我想知道从基于索引的“掩码”到布尔掩码的更好方法。

我将SSCCE coords减少到两个真正的dim而不是IR²vecs我使用复数表示 - 它稍微变平了;该主题不受该简化的影响。

#!/usr/bin/env python2.7
import numpy as np

# ----------------------mocking the static data ----------------------72

phi = np.pi/4.

# corners of an axis-aligned square in the complex plane
coords = np.array(
    [
        np.complex(np.cos(a), np.sin(a))
        for a in np.arange(phi, 8 * phi, 2 * phi)
    ])

# appending cornes for a square turned left by pi/4 = 45 deg
w = coords[0]
coords = np.append(coords, coords * w)
# print np.round(coords)

# indices for both quads
faces = np.arange(8).reshape(2, 4)

# generating dummy duplicates
faces = np.append(faces, faces, axis=0)
print faces
# which are to be excluded
apriori_face_mask = [True, True, False, False]

# reverse indexing
vertex_faces = np.append(np.zeros(4, dtype=int), np.ones(4, dtype=int))
# for the duplicates
vertex_faces = np.append(vertex_faces, vertex_faces)

# ---------------------------- runtime -------------------------------72

# selecting vertices by certain criteria
runtime_mask = (np.imag(coords) > (float(1.) - np.finfo(float).eps))

# selecting the corresponding face
selected_face_indices = vertex_faces[np.where(runtime_mask)]

# ################################################################
# (A) this is what I'd like to improve
# ################################################################
boolean_mask_from_selected_face_indices = [
    i in selected_face_indices for i in range(faces.shape[0])
]
# ################################################################

# -----------------------------------------------------------------
# (B) combining the two filters
selected_faces = faces[
    np.logical_and(apriori_face_mask,
                   boolean_mask_from_selected_face_indices)
]
# ----------------------------------------------------------------------

assert(selected_faces.shape[0] == 1)

try:
    import matplotlib.pyplot as plt
    res = coords[selected_faces.flat]
    plt.fill(np.real(res), np.imag(res), facecolor="r")
    plt.show()
except ImportError as e:
    print("No matplotlib.pyplot; text result is:")
    print(selected_faces)

重要的是要说明,对于我的工作,我不需要重新编制面部索引;对于我的需求,它足够好,只有面部选择反映当前的工作集,携带整个顶点负载不会花费我任何东西。

这意味着如果可以避免,我也不想为任何重新索引和相关费用而烦恼。

numpy版本是1.9.1 平台是64位(Debian jessie amd64)

修改 好的,这个

arr = [False for _ in (range(faces.shape[0]))]
for i in selected_face_indices:
    arr[i] = True
boolean_mask_from_selected_face_indices = arr

显然更好,但我还是想以某种方式避免那个循环

1 个答案:

答案 0 :(得分:2)

您可以直接使用索引列表来索引数组。所以这会奏效:

import numpy as np
indices = [1, 3, 7]
mask = np.zeros(10, dtype=np.bool)
mask[indices] = True
print(mask) # [False  True False  True False False False  True False False]