【问题标题】:python bin data and return bin midpoint (maybe using pandas.cut and qcut)python bin 数据和返回 bin 中点(可能使用 pandas.cut 和 qcut)
【发布时间】:2015-12-21 01:34:14
【问题描述】:

我可以让 pandas cut/qcut 函数返回 bin 端点或 bin 中点而不是 bin 标签字符串吗?

目前

pd.cut(pd.Series(np.arange(11)), bins = 5)

0     (-0.01, 2]
1     (-0.01, 2]
2     (-0.01, 2]
3         (2, 4]
4         (2, 4]
5         (4, 6]
6         (4, 6]
7         (6, 8]
8         (6, 8]
9        (8, 10]
10       (8, 10]
dtype: category

带有类别/字符串值。我想要的是

0     1.0
1     1.0
2     1.0
3     3.0
4     3.0

用数值表示 bin 的边缘或中点。

【问题讨论】:

    标签: python pandas binning


    【解决方案1】:

    我注意到一个类别有一个mid 属性,因此您可以通过apply 计算中间:

    In [1]: import pandas as pd
       ...: import numpy as np
       ...: df = pd.DataFrame({"val":np.arange(11)})
       ...: df["bins"] = pd.cut(df["val"], bins = 5)
       ...: df["bin_centres"] = df["bins"].apply(lambda x: x.mid)
       ...: df
    Out[1]:
        val          bins bin_centres
    0     0  (-0.01, 2.0]       0.995
    1     1  (-0.01, 2.0]       0.995
    2     2  (-0.01, 2.0]       0.995
    3     3    (2.0, 4.0]       3.000
    4     4    (2.0, 4.0]       3.000
    5     5    (4.0, 6.0]       5.000
    6     6    (4.0, 6.0]       5.000
    7     7    (6.0, 8.0]       7.000
    8     8    (6.0, 8.0]       7.000
    9     9   (8.0, 10.0]       9.000
    10   10   (8.0, 10.0]       9.000
    

    【讨论】:

      【解决方案2】:

      我看到这是一个旧帖子,但我还是会冒昧地回答它。

      现在可以使用left 和right 访问分类区间的端点。

      s = pd.cut(pd.Series(np.arange(11)), bins = 5)
      
      mid = [(a.left + a.right)/2 for a in s]
      Out[34]: [0.995, 0.995, 0.995, 3.0, 3.0, 5.0, 5.0, 7.0, 7.0, 9.0, 9.0]
      

      由于区间向左开而向右闭,“第一个”区间(从 0 开始的区间)实际上从 -0.01 开始。要使用 0 作为左值获得中点,您可以这样做

      mid_alt = [(a.left + a.right)/2 if a.left != -0.01 else a.right/2 for a in s]
      Out[35]: [1.0, 1.0, 1.0, 3.0, 3.0, 5.0, 5.0, 7.0, 7.0, 9.0, 9.0]
      

      或者,你可以说区间向左闭合,向右打开

      t = pd.cut(pd.Series(np.arange(11)), bins = 5, right=False)
      Out[38]: 
      0       [0.0, 2.0)
      1       [0.0, 2.0)
      2       [2.0, 4.0)
      3       [2.0, 4.0)
      4       [4.0, 6.0)
      5       [4.0, 6.0)
      6       [6.0, 8.0)
      7       [6.0, 8.0)
      8     [8.0, 10.01)
      9     [8.0, 10.01)
      10    [8.0, 10.01)
      

      但是,如您所见,您在最后一个区间遇到了同样的问题。

      【讨论】:

        【解决方案3】:

        “IntervalIndex”正在开发中 proposal,这将使此类操作非常简单。

        但是现在,您可以通过传递 retbins 参数来获取 bin 并计算中点。

        In [8]: s, bins = pd.cut(pd.Series(np.arange(11)), bins = 5, retbins=True)
        
        In [11]: mid = [(a + b) /2 for a,b in zip(bins[:-1], bins[1:])]
        
        In [13]: s.cat.rename_categories(mid)
        Out[13]: 
        0     0.995
        1     0.995
        2     0.995
        3     3.000
        4     3.000
        5     5.000
        6     5.000
        7     7.000
        8     7.000
        9     9.000
        10    9.000
        dtype: category
        Categories (5, float64): [0.995 < 3.000 < 5.000 < 7.000 < 9.000]
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2016-02-13
          • 2016-04-20
          • 2018-11-28
          • 2021-07-29
          • 1970-01-01
          • 2021-05-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多