代码之家  ›  专栏  ›  技术社区  ›  stone rock

如何用数值替换分类值?

  •  1
  • stone rock  · 技术社区  · 6 年前

    在dataframe中,所有值都是 object 如: >20 , <1 , >5 等。 上界= 35 和下颚= 0 所以如果列中的值是 <一 然后我想用平均值替换这个值,即(0(lowerbound值)+1)/2=0.5

    如果值为 >20个 然后我想用(20+35(上限值))/2=27.5替换这个值

    如何将现有的数据文件转换为所需的窗体。注:中的值 col1 是字符串而不是数值。

    现有数据文件:

    d = {'col1': ['>20', '<5', '<1','>10']}
    df = pd.DataFrame(data=d)
    df
          col1  
    0     >20     
    1     <5
    2     <1
    3     >10
    4     100-200
    5     10-20
    

    我想在上面转换 df 致:

          col1  
    0     27.5     <--- (20+35)/2
    1     2.5      <--- (5+0)/2
    2     0.5      <--- (1+0)/2
    3     22.5     <--- (10+35)/2
    4     150      <--- (100+200)/2
    5     15       <--- (10+20)/2
    
    2 回复  |  直到 6 年前
        1
  •  2
  •   jezrael    6 年前

    使用 replace 通过子串然后 pandas.eval 以下内容:

    df['col2'] = pd.eval(df['col1'].replace(['>','<'], ['35+','0+'], regex=True)) / 2
    print (df)
      col1  col2
    0  >20  27.5
    1   <5   2.5
    2   <1   0.5
    3  >10  22.5
    

    编辑:

    df['col2'] = pd.eval(df['col1'].replace(['>','<','-'], ['35+','0+','+'], regex=True)) / 2
    print (df)
          col1  col2
    0      >20  27.5
    1       <5   2.5
    2       <1   0.5
    3      >10  22.5
    4  100-200   150
    5    10-20    15
    

    编辑:

    上面的probl解决方案是它只能工作到100行吗(参见 bug ,因此需要其他解决方案:

    df = pd.read_csv('train_jqd04QH(1).csv', usecols=['experience', 'company_size'])
    
    
    s1 = df['experience'].replace(['>','<', '-'], ['35+','0+', '+'], regex=True)
    
    #added anothr repalce string, `\+$` is match last + like 1000+
    s2 = df['company_size'].replace(['>','<', '-', '/', '\+$'], 
                                    ['35+','0+', '+', '+', '+35'], regex=True)
    
    df['experience'] = s1.str.split('+', expand=True).astype(float).mean(axis=1)
    df['company_size'] = s2.str.split('+', expand=True).astype(float).mean(axis=1)
    
    print (df.head())
    
       experience  company_size
    0         3.0         300.0
    1        14.0           5.0
    2         6.0          74.5
    3        14.0          74.5
    4         8.0           NaN
    
        2
  •  0
  •   westr    6 年前

    你可以用 pd.DataFrame.replace 为了这个。

    df.replace({'>20':27.5, '<5':2.5, '<1':0.5, '>10':22.5})
    

    虽然我觉得你想填写的值计算得不好。范围是否不如下:

    20 - 35 --> 27.5
    10 - 20 --> 15
    1  -  5 --> 3
    0  -  1 --> 0.5