【问题标题】:slicing numpy arrays by combining indices and expression masks通过组合索引和表达式掩码对 numpy 数组进行切片
【发布时间】:2015-02-11 09:13:30
【问题描述】:

我要分析一个(约 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 坐标减少到两个实数暗度,而不是 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

显然更好,但我仍然想以某种方式避免该循环

【问题讨论】:

    标签: python arrays python-2.7 numpy slice


    【解决方案1】:

    您可以直接使用索引列表来索引您的数组。所以这会起作用:

    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]
    

    【讨论】:

    • 当然。你是绝对正确的。我知道我错过了什么。 :) 非常感谢!
    猜你喜欢
    • 1970-01-01
    • 2017-07-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-05-02
    • 1970-01-01
    • 2018-11-07
    • 2023-03-15
    相关资源
    最近更新 更多