Python - 简单的"比较"方法将一个数组映射到另一个数组

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的插入点以维护排序顺序.参数lohi可用于指定应考虑的列表的子集; 默认情况下,使用整个列表.如果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