【问题标题】:Binning in python pandas dataframe (not manually setting bins)在 python pandas 数据框中分箱(不手动设置箱)
【发布时间】:2018-11-13 22:33:06
【问题描述】:

我有一个数据框。我想合并值并将其附加到新列。我可以用 pd.cut 做到这一点。但问题是,我使用 pd.cut 手动设置标签和垃圾箱。但是,我只想设置步长(不是 bin 编号)。我也尝试了 np.linespace、np.arange 但我必须指定起点和终点以及 bin 计数。但是可能有一个数据框,我无法知道数据框中的最大和最小数字

df = pd.DataFrame([10, 10, 23, 42, 51, 33, 52, 42,44, 67, 65, 12, 10, 2, 3, 2, 77, 76],columns=['values'])
bins = [0, 10, 20,30, 40, 50, 60, 70]
labels = ['0-10', '10-20', '20-30', '30-40', '40-50', '50-60', '60-70']
df['bins'] = pd.cut(df['values'], bins, labels=labels)
print (df)

    values   bins
0       10   0-10
1       10   0-10
2       23  20-30
3       42  40-50
4       51  50-60
5       33  30-40
6       52  50-60
7       42  40-50
8       44  40-50
9       67  60-70
10      65  60-70
11      12  10-20
12      10   0-10
13       2   0-10
14       3   0-10
15       2   0-10
16      77    NaN
17      76    NaN

这是我的输出,我想获得相同的输出,但不想手动设置 bin 和标签 p.s.正如你从这里看到的,如果我的值大于 70,它将是 Nan。所以这也是我想设置步长“10”的原因。我可以有持续值,所以我希望它使用步长 10 自动标记

非常感谢您的帮助

谢谢!!!

【问题讨论】:

    标签: python pandas numpy dataframe bin


    【解决方案1】:

    只是对您的代码稍作改动,请注意我在您的 df 末尾添加了一个值为 93 的行。

    df = pd.DataFrame([10, 10, 23, 42, 51, 33, 52, 42,44, 67, 65, 12, 10, 2, 3, 2, 77, 76, 93],columns=['values'])
    bins = np.arange(0,df['values'].max() + 10, 10)
    df['bins'] = pd.cut(df['values'], bins)
    
    values  bins
    0   10  (0, 10]
    1   10  (0, 10]
    2   23  (20, 30]
    3   42  (40, 50]
    4   51  (50, 60]
    5   33  (30, 40]
    6   52  (50, 60]
    7   42  (40, 50]
    8   44  (40, 50]
    9   67  (60, 70]
    10  65  (60, 70]
    11  12  (10, 20]
    12  10  (0, 10]
    13  2   (0, 10]
    14  3   (0, 10]
    15  2   (0, 10]
    16  77  (70, 80]
    17  76  (70, 80]
    18  93  (90, 100]
    

    编辑:要按照 cmets 的要求在 bin 中包含零,请将参数 include_lowest 设置为 True

    df = pd.DataFrame([0, 0, 0, 10, 10, 23, 42, 51, 33, 52, 42,44, 67, 65, 12, 10, 2, 3, 2, 77, 76, 93],columns=['values'])
    bins = np.arange(0,df['values'].max() + 10, 10)
    df['bins'] = pd.cut(df['values'], bins, include_lowest=True)
    

    你得到

       values   bins
    0   0   (-0.001, 10.0]
    1   0   (-0.001, 10.0]
    2   0   (-0.001, 10.0]
    3   10  (-0.001, 10.0]
    4   10  (-0.001, 10.0]
    5   23  (20.0, 30.0]
    6   42  (40.0, 50.0]
    7   51  (50.0, 60.0]
    8   33  (30.0, 40.0]
    9   52  (50.0, 60.0]
    10  42  (40.0, 50.0]
    11  44  (40.0, 50.0]
    12  67  (60.0, 70.0]
    13  65  (60.0, 70.0]
    14  12  (10.0, 20.0]
    15  10  (-0.001, 10.0]
    16  2   (-0.001, 10.0]
    17  3   (-0.001, 10.0]
    18  2   (-0.001, 10.0]
    19  77  (70.0, 80.0]
    20  76  (70.0, 80.0]
    21  93  (90.0, 100.0]
    

    【讨论】:

    • 哦,我明白了。谢谢,这正是我需要的。对不起,我缺乏编程知识,所以作为你选择的起点,作为你在数据框中选择最大值的停止点,但他们为什么要在 df['values'].max() 中添加“10”?跨度>
    • @Mischa,我们所有人都处于不同的学习阶段,所以无需抱歉。在 range 函数中,不包括上边界,例如: range(0,100, 10) 只会给你从 0 到 90 的数字。+10 会处理
    • 我接受了这个答案,但我现在有另一个问题,如果我在数据框中有零,np.arrange 不能将它包含在垃圾箱中。我应该使用另一个函数还是有办法用 np.arange 包含零
    • df = pd.DataFrame([0, 0, 0, 10, 10, 23, 42, 51, 33, 52, 42,44, 67, 65, 12, 10, 2, 3 , 2, 77, 76, 93],columns=['values']) 如果这是我的数据框,则零的 bin 将为 NaN
    • @Syed Ahmed,您可以将 np.arange(0,df['values'].max() + 10, 10) 更改为 np.arange(-200, 210, 10)。或 np.arange(df['values'].min(), df['values'].max() + 10, 10)
    【解决方案2】:

    @Vaishali 基本上回答了这个问题,但只是补充一点,为了以编程方式获取您想要的标签,您可以在列表理解中使用 bin 值,从而产生下面的字符串标签(匹配您想要的框架)

    df = pd.DataFrame([10, 10, 23, 42, 51, 33, 52, 42,44, 67, 65, 12, 10, 2, 3, 2, 77, 76],columns=['values'])
    bins = np.arange(0,df['values'].max() + 10, 10)
    labels = ['-'.join(map(str,(x,y))) for x, y in zip(bins[:-1], bins[1:])]
    
    df['bins'] = pd.cut(df['values'], bins = bins, labels=labels)
    
    >>> df
        values   bins
    0       10   0-10
    1       10   0-10
    2       23  20-30
    3       42  40-50
    4       51  50-60
    5       33  30-40
    6       52  50-60
    7       42  40-50
    8       44  40-50
    9       67  60-70
    10      65  60-70
    11      12  10-20
    12      10   0-10
    13       2   0-10
    14       3   0-10
    15       2   0-10
    16      77  70-80
    17      76  70-80
    

    【讨论】:

      【解决方案3】:

      这里我们解决了这个问题,简单的使用了 numpy 函数的 Binning Function 和 bit help。

      df = pd.DataFrame([10, 10, 23, 42, 51, 33, 52, 42,44, 67, 65, 12, 10, 2, 3, 2,  77, 76],columns=['values'])
      max = df['value'].max()
      df['Bins'] = pd.cut(df['value'], np.arange(0, max + 10, 10))
      print(df)
      

      【讨论】:

      • 仅代码的答案通常不赞成 SO。请编辑您的答案,以说明您的代码的作用以及它如何解决 OP 的问题。
      • 虽然此代码可能会解决问题,including an explanation 关于如何以及为什么解决问题将真正有助于提高您的帖子质量,并可能导致更多的赞成票。请记住,您正在为将来的读者回答问题,而不仅仅是现在提问的人。请edit您的答案添加解释,并说明适用的限制和假设。
      猜你喜欢
      • 1970-01-01
      • 2018-04-06
      • 2013-06-01
      • 2020-07-03
      • 2018-04-15
      • 2016-10-07
      • 1970-01-01
      • 1970-01-01
      • 2023-02-21
      相关资源
      最近更新 更多