【问题标题】:Python: Checking to which bin a value belongsPython:检查值属于哪个bin
【发布时间】:2013-02-03 13:39:04
【问题描述】:

我有一个值列表和一个 bin 边缘列表。现在我需要检查它们所属的 bin 的所有值。有没有比遍历值然后遍历 bin 并检查值是否属于当前 bin 更 Pythonic 的方法,例如:

my_list = [3,2,56,4,32,4,7,88,4,3,4]
bins = [0,20,40,60,80,100]

for i in my_list:
    for j in range(len(bins)):
        if bins(j) < i < bins(j+1):
            DO SOMETHING

这对我来说看起来不太漂亮。 谢谢!

【问题讨论】:

  • 首先对列表进行排序。

标签: python range binning


【解决方案1】:

可能为时已晚,但为了将来参考,numpy 有一个功能可以做到这一点:

http://docs.scipy.org/doc/numpy/reference/generated/numpy.digitize.html

>>> my_list = [3,2,56,4,32,4,7,88,4,3,4]
>>> bins = [0,20,40,60,80,100]
>>> np.digitize(my_list,bins)
array([1, 1, 3, 1, 2, 1, 1, 5, 1, 1, 1])

结果是一个索引数组,对应于来自 my_list 中的每个元素的 bin 中的 bin。 请注意,该函数还将对位于您的第一个和最后一个 bin 边缘之外的值进行 bin 处理:

>>> my_list = [-5,200]
>>> np.digitize(my_list,bins)
array([0, 6])

Pandas 也有类似的东西:

http://pandas.pydata.org/pandas-docs/dev/basics.html#discretization-and-quantiling

>>> pd.cut(my_list, bins)
Categorical: 
array(['(0, 20]', '(0, 20]', '(40, 60]', '(0, 20]', '(20, 40]', '(0, 20]',
       '(0, 20]', '(80, 100]', '(0, 20]', '(0, 20]', '(0, 20]'], dtype=object)
Levels (5): Index(['(0, 20]', '(20, 40]', '(40, 60]', '(60, 80]',
                   '(80, 100]'], dtype=object)

【讨论】:

    【解决方案2】:

    也许这会帮助你走上正轨:

    >>> import itertools
    >>> my_list = [3,2,56,4,32,4,7,88,4,3,4]
    >>> for k, g in itertools.groupby(sorted(my_list), lambda x: x // 20 * 20):
    ...     print k, list(g)
    ... 
    0 [2, 3, 3, 4, 4, 4, 4, 7]
    20 [32]
    40 [56]
    80 [88]
    

    【讨论】:

      【解决方案3】:

      首先,当值等于 bin 边界时,您的代码将失败 --

      改变

      if bins(j) < i < bins(j+1):
      

      在某处有一个&lt;= 签名。

      之后,使用bisect 模块

      import bisect
      bisect.bisect(x, bins)
      

      bisect.bisect_right

      取决于当值位于 bin 边界时,您是希望采用较高的 bin 还是较低的 bin。

      【讨论】:

      • 我认为bisect 的论点是相反的。
      • 另外:bisectbisect_right 是同一个功能。 bisect_left 用于更改哪个 bin 包含边界
      猜你喜欢
      • 2012-02-14
      • 2018-06-05
      • 2021-09-27
      • 1970-01-01
      • 1970-01-01
      • 2019-02-09
      • 1970-01-01
      • 1970-01-01
      • 2019-02-14
      相关资源
      最近更新 更多