我有一个数组 a = [1, 2, 3, 4, 5, 6]
和 b = [1, 3, 5]
我会喜欢映射 a
这样 a
中位于 b
元素之间的每个元素都将映射到 b 的索引
是包含 a
的上限。这不是最好的文字解释,但这是一个例子
a = 1 -> 0 because a <= first element of b
a = 2 -> 1 because b[0] < 2 <= b[1] and b[1] = 3
a = 3 -> 1
a = 4 -> 2 because b[1] < 4 <= b[2]
所以我想要的最终结果是 f(a, b) = [0, 1, 1, 2, 2, 2]
我知道我可以循环并解决它,但我想知道在 pandas/numpy 中是否有一种聪明、快速(矢量化)的方法来做到这一点
最佳答案
使用 python 的 bisect
模块:
from bisect import bisect_left
a = [1, 2, 3, 4, 5, 6]
b = [1, 3, 5]
def f(_a, _b):
return [bisect_left(_b, i) for i in _a]
print(f(a, b))
bisect — Array bisection algorithm
This module provides support for maintaining a list in sorted order without having to sort the list after each insertion. For long lists of items with expensive comparison operations, this can be an improvement over the more common approach. The module is called bisect because it uses a basic bisection algorithm to do its work. The source code may be most useful as a working example of the algorithm (the boundary conditions are already right!).
The following functions are provided:
bisect.bisect_left(a, x, lo=0, hi=len(a))
Locate the insertion point for x in a to maintain sorted order. The parameters lo and hi may be used to specify a subset of the list which should be considered; by default the entire list is used. If x is already present in a, the insertion point will be before (to the left of) any existing entries. The return value is suitable for use as the first parameter to
list.insert()
assuming that a is already sorted.The returned insertion point i partitions the array a into two halves so that
all(val < x for val in a[lo:i])
for the left side andall(val >= x for val in a[i:hi])
for the right side.
关于Python - "comparison"将一个数组映射到另一个数组的简单方法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44544659/