基于NumPy数组逐元素比较筛选符合条件的票务数据
解决方案
核心逻辑梳理
你的筛选规则本质是:任意两个票务之间,不能出现「一方旅行时间更长且价格更高」或「一方旅行时间更短且价格更低」的情况。我们可以通过「时间差×价格差」的符号来快速判断:
- 若票务i比j时间更长且价格更低 → (time_i - time_j)为正,(price_i - price_j)为负 → 乘积为负,符合规则
- 若票务i比j时间更短且价格更高 → (time_i - time_j)为负,(price_i - price_j)为正 → 乘积为负,符合规则
- 若出现违反规则的情况 → 乘积为正,直接排除该票务
NumPy实现代码
import numpy as np # 定义票务数据 tickets = np.array([ ['A', 10, 1700], ['B', 9, 2000], ['C', 8, 1800], ['D', 7.5, 2300], ['E', 6, 2200] ], dtype=object) # 提取各字段数组 names = tickets[:, 0] times = tickets[:, 1].astype(float) prices = tickets[:, 2].astype(float) # 计算时间差矩阵(每行对应一个票务与所有票务的时间差) time_diff = times.reshape(-1, 1) - times # 计算价格差矩阵(每行对应一个票务与所有票务的价格差) price_diff = prices.reshape(-1, 1) - prices # 计算时间差×价格差的乘积矩阵 product = time_diff * price_diff # 忽略自身对比的情况(对角线元素设为-1,不影响判断) np.fill_diagonal(product, -1) # 筛选符合条件的票务:所有对比的乘积都为负 satisfy_mask = np.all(product < 0, axis=1) # 生成结果列表 satisfies = names[satisfy_mask].tolist() not_satisfies = names[~satisfy_mask].tolist() print(f"satisfies = {satisfies}") print(f"not_satisfies = {not_satisfies}")
代码解释
- 数据准备:将票务数据转为NumPy数组,拆分出名称、时间、价格三个独立数组
- 广播运算:利用NumPy的广播特性,一次性计算所有票务两两之间的时间差和价格差,得到n×n的对比矩阵
- 规则判断:通过乘积符号快速判断是否符合规则,
np.all(product < 0, axis=1)检查每个票务与所有其他票务的对比是否全部符合要求 - 结果输出:根据布尔掩码拆分得到符合/不符合条件的票务列表
运行代码后会输出:
satisfies = ['A', 'B', 'C'] not_satisfies = ['D', 'E']
内容的提问来源于stack exchange,提问作者Dinc Kirikci
相关产品推荐
相关产品推荐

