You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何提取列表中满足元素对双条件的numpy数组对

问题根源

代码没有剔除任何点、返回10000个点的原因有三点:

  • 判断条件缺失:你写的conditions函数仅校验了点是否在外接矩形范围内,而生成kx时x已经被限制在[-1/√3, 1/√3],ky也已经被限制在[-2/3, 2/3],所有候选点天然满足你写的判断规则,自然掩码全为True。你完全漏掉了正六边形斜边的约束条件。
  • 点生成逻辑错误:用列表推导式对kx、ky做笛卡尔积生成的是规则网格点,不是独立随机分布的点集。
  • API使用错误:np.extract会将数组扁平化后提取元素,最终无法得到N行2列的点坐标结构。

你当前外接矩形对应的是左右边竖直、上下为顶点的正六边形,它的完整边界约束有三个:

  • 左右竖直边:|x| ≤ 1/√3
  • 上下顶点边界:|y| ≤ 2/3
  • 四条斜边约束:|x|/√3 + |y| ≤ 2/3(这是裁掉矩形四个角多余点的核心判断,也是你之前漏掉的逻辑)
修正后的拒绝采样实现

拒绝采样是实现这个需求最简单的方案,因为外接矩形内点的有效率为75%,采样效率很高:

import numpy as np
from scipy import stats as sps

target_count = 100  # 目标生成的六边形内点数量
valid_points = []

while len(valid_points) < target_count:
    # 每批生成2倍剩余所需量的候选点,减少循环次数
    batch_size = (target_count - len(valid_points)) * 2
    # 独立生成外接矩形内的随机x、y坐标,按下标一一配对为点
    kx = 1 / np.sqrt(3) * sps.uniform.rvs(loc=-1, scale=2, size=batch_size)
    ky = 2 / 3 * sps.uniform.rvs(loc=-1, scale=2, size=batch_size)
    # 应用完整六边形约束生成掩码
    mask = (
        (np.abs(kx) <= 1 / np.sqrt(3))
        & (np.abs(ky) <= 2 / 3)
        & (np.abs(kx) / np.sqrt(3) + np.abs(ky) <= 2 / 3)
    )
    # 收集符合条件的点
    valid_points.extend(zip(kx[mask], ky[mask]))

# 截取刚好目标数量的点,转为numpy坐标数组
hex_points = np.array(valid_points[:target_count])
print(f"生成六边形内随机点数量:{len(hex_points)}")
其他可选方案

如果不想用拒绝采样,可以将正六边形拆分为6个以原点为公共顶点的等边三角形,先按三角形面积权重随机选择目标三角形,再在三角形内生成均匀随机点,这种方案没有点浪费,但需要额外写三角形采样逻辑,对于小规模点集场景,拒绝采样的实现成本和运行效率已经足够优。

内容的提问来源于stack exchange,提问作者goroshek

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.30 14:39:08