python - 过滤 Numpy 数组以获取不包括相等值但符号相反的负值
问题描述
我有
x = np.array([20000, 700, 1000, -5000, -250, 30, -1000, 50, -30, 75, -999])
我想排除这些值-1000
,-30
因为它们前面x
有对应的值1000
。30
我想得到
y = np.array([-5000, -250, -999])
解决方案
有一个快速O(n log n)
有效和矢量化的 Numpy 实现。
这个想法是在x
(with np.unique
) 中找到唯一值,并为每个唯一值定位其第一个位置。然后你可以选择if is found before 和v
中的值。要查找之前是否找到它,您可以在已排序的唯一值(带有)中执行二分法,以查找当前索引是否大于找到的索引(在唯一值中)。x
-v
v < 0
np.searchsorted
这是生成的代码:
xUnique, xFirstPos = np.unique(x, return_index=True)
xIsNeg = x < 0
xNeg = -x
xNegUniquePos = np.searchsorted(xUnique, xNeg)
xNegIsFound = xUnique[xNegUniquePos] == xNeg
xHasNegBefore = np.logical_and(xNegIsFound, xFirstPos[xNegUniquePos] < np.arange(len(x)))
result = x[np.logical_and(xIsNeg, np.logical_not(xHasNegBefore))]
print(result)
以下是一些示例的结果:
x = np.array([20000, 700, 1000, -5000, -250, 30, -1000, 50, -30, 75, -999])
result = np.array([-5000, -250, -999])
x = np.array([-5, 5, -5])
result = np.array([-5])
以下是大小为 100_000 的随机数组的时序(33% 的负值在 -1_000_000 到 2_000_000 范围内):
Mad Physicist's Numpy implementation: 38900.0 ms
Emi OB's implementation: 1360.0 ms (incorrect so far)
Mad Physicist's pure Python implementation: 40.0 ms
This implementation: 14.1 ms
到目前为止,这个实现比其他实现快得多。对于这种输入大小,Mad Physicist 的 Numpy 实现占用了几 GiB 的内存,而其他解决方案(包括这个)占用的内存不超过 10 MiB,这毫无价值。
推荐阅读
- json - 谷歌脚本从电子表格中获取 json 数据
- c++ - OpenMPI 如何针对 long long 数组执行 MPI_Allreduce
- php - App\Post::categorys 必须返回一个关系实例,但返回的是“null”。是否使用了“return”关键字?拉拉维尔
- python - 如何从 Apache Beam 中的 Pcollection 中获取一个元素
- scala - scala 元组列表,查找每个 Key 最大值,不使用 groupBy
- coq - 在 Coq 中解析简单的命令式语言
- php - 在 Laravel 6 中进行插入的最佳方法
- google-apps-script - GAS - 获取所有命名范围的脚本,包括受保护的范围 - 没有工作
- teamcity - 如何为 teamcity 代理安装附加软件?
- c# - c#中如何获取当前正在执行的方法的返回类型和返回类型的泛型?