Mic*_*ael 5 python arrays numpy pandas
我有一个数组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]
Run Code Online (Sandbox Code Playgroud)
所以我想要的最终产品是 f(a, b) = [0, 1, 1, 2, 2, 2]
我知道我可以循环并解决它但我想知道在pandas/numpy中是否有一种聪明,快速(矢量化)的方法来做到这一点
小智 7
使用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))
Run Code Online (Sandbox Code Playgroud)
bisect - 数组二分算法
此模块支持按排序顺序维护列表,而无需在每次插入后对列表进行排序.对于具有昂贵比较操作的长项目列表,这可以是对更常见方法的改进.该模块称为bisect,因为它使用基本的二分算法来完成其工作.源代码作为算法的工作示例可能是最有用的(边界条件已经正确!).
提供以下功能:
bisect.bisect_left(a, x, lo=0, hi=len(a))
在a中找到x的插入点以维护排序顺序.参数lo和hi可用于指定应考虑的列表的子集; 默认情况下,使用整个列表.如果x已经存在于a中,则插入点将位于任何现有条目之前(左侧).返回值适合用作假设a已经排序的第一个参数.
list.insert()
返回的插入点i将阵列a分成两半,
all(val < x for val in a[lo:i])
以便左侧和all(val >= x for val in a[i:hi])
右侧.
参考:https: //docs.python.org/3/library/bisect.html