【问题标题】:how to Replace column values with several conditions如何用多个条件替换列值
【发布时间】:2021-08-17 05:33:02
【问题描述】:

我有一栏如下:

     A          B
0    0      20.00
1    1      35.00
2    2      75.00
3    3      29.00
4    4     125.00
5    5      16.00
6    6      52.50
7    7        NaN
8    8        NaN
9    9        NaN
10  10        NaN
11  11        NaN
12  12        NaN
13  13     239.91
14  14      22.87
15  15      52.74
16  16      37.20
17  17      27.44
18  18      57.01
19  19      29.88

我想按如下方式更改列的值 如果0<B<10.0,则将B的单元格值替换为“0到10” 如果10.1<B<20.0,则将B的单元格值替换为“10到20” 像这样继续,直到达到最大范围。 我试过了

ds['B'] = np.where(ds['B'].between(10.0,20.0), "10 to 20", ds['B'])

但是一旦我执行了这个操作,DataFrame 就被字符串"10 to 20" 占用了,所以我不能对DataFrame 的剩余值再次执行这个操作。在这一步之后,DataFrame 如下所示:

     A         B
0    0  10 to 20
1    1      35.0
2    2      75.0
3    3      29.0
4    4     125.0
5    5  10 to 20
6    6      52.5
7    7       nan
8    8       nan
9    9       nan
10  10       nan
11  11       nan
12  12       nan
13  13    239.91
14  14     22.87
15  15     52.74
16  16      37.2
17  17     27.44
18  18     57.01
19  19     29.88

以下行:ds['B'] = np.where(ds['B'].between(20.0,30.0), "20 to 30", ds['B']) 将抛出 TypeError: '>=' not supported between instances of 'str' and 'float'

我如何编写代码以一次将 DataFrame 中的所有值更改为这些范围字符串?

【问题讨论】:

    标签: python pandas replace conditional-statements


    【解决方案1】:

    这可以用更少的代码来完成,因为这实际上只是字符串格式的问题。

    ds['B'] = ds['B'].apply(lambda x: f'{int(x/10) if x>=10 else ""}0 to {int(x/10)+1}0' if pd.notnull(x) else x)
    

    【讨论】:

      【解决方案2】:

      您可以创建一个自定义函数,将每个范围映射到一个字符串。比如19.0会映射到“10到20”,然后把这个函数应用到每一行。

      我已经编写了代码,以便范围的最小值和最大值可推广到 DataFrame,并采用 10 的倍数。

      import numpy as np
      import pandas as pd
      
      ## copy and paste your DataFrame
      ds = pd.read_clipboard()
      
      # floor to nearest multiple of 10
      ds_min = ds['B'].min()//10*10
      # ceiling to the nearest multiple of 10
      ds_max = round(ds['B'].max(),-1)
      
      ranges = np.linspace(ds_min, ds_max, ((ds_max-ds_min)/10)+1)
      
      def map_value_to_string(value):
          for idx in range(1,len(ranges)):
              low_value, high_value = ranges[idx-1], ranges[idx]
              if low_value < value <= high_value:
                  return f"{int(low_value)} to {int(high_value)}"
              else:
                  continue
      
      ds['B'] = ds['B'].apply(lambda x: map_value_to_string(x))
      

      输出:

      >>> ds
           A           B
      0    0    10 to 20
      1    1    30 to 40
      2    2    70 to 80
      3    3    20 to 30
      4    4  120 to 130
      5    5    10 to 20
      6    6    50 to 60
      7    7        None
      8    8        None
      9    9        None
      10  10        None
      11  11        None
      12  12        None
      13  13  230 to 240
      14  14    20 to 30
      15  15    50 to 60
      16  16    30 to 40
      17  17    20 to 30
      18  18    50 to 60
      19  19    20 to 30
      

      【讨论】:

        【解决方案3】:

        构建您的垃圾箱和标签并使用pd.cut:

        bins = np.arange(0, df["B"].max() // 10 * 10 + 10, 10).astype(int)
        labels = [' to '.join(t) for t in zip(bins[:-1].astype(str), bins[1:].astype(str))]
        
        df["B"] = pd.cut(df["B"], bins=bins, labels=labels)
        
        >>> df
             A           B
        0    0    10 to 20
        1    1    30 to 40
        2    2    70 to 80
        3    3    20 to 30
        4    4  120 to 130
        5    5    10 to 20
        6    6    50 to 60
        7    7         NaN
        8    8         NaN
        9    9         NaN
        10  10         NaN
        11  11         NaN
        12  12         NaN
        13  13         NaN
        14  14    20 to 30
        15  15    50 to 60
        16  16    30 to 40
        17  17    20 to 30
        18  18    50 to 60
        19  19    20 to 30
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2021-10-10
          • 2021-10-18
          • 2016-01-21
          • 2021-07-19
          • 2019-09-08
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多