【问题标题】:Pandas: convert a series which contains strings like "10%" and "0.10" into numericPandas:将包含“10%”和“0.10”等字符串的系列转换为数字
【发布时间】:2022-06-15 21:44:50
【问题描述】:

将包含“10%”和“0.10”类型字符串的 Pandas 系列转换为数值的最佳方法是什么?

我知道,如果我有一个只有“0.10”类型字符串的系列,我可以做pd.to_numeric

我也知道,如果我有一系列“10%”类型的字符串,我可以先做str.replace("%",""),然后再做pd.to_numeric,然后除以100。

我遇到的问题是一系列混合了“0.10”和“10%”类型的字符串。如何最好地将其转换为具有正确数字类型的系列。

我想我可以通过首先使用 True / False 制作一个临时系列来做到这一点,具体取决于字符串中是否包含“%”,然后根据该字符串应用一个函数。但这似乎效率低下。

有没有更好的办法?

我尝试过的参考:

mixed = pd.Series(["10%","0.10","5.5%","0.02563"])
mixed.str.replace("%","").astype("float")/100

0    0.100000
1    0.001000
2    0.055000
3    0.000256
dtype: float64
# This doesn't work, because even the 0.10 and 0.02563 are divided by 100.

【问题讨论】:

    标签: python pandas string format number-formatting


    【解决方案1】:

    基于this answer 的一个非常简洁的解决方案是:

    from pandas import Series, to_numeric
    
    mixed = Series(["10%", "0.10", "5.5%", "0.02563"])
    
    print(to_numeric(mixed.str.replace("%", "e-2")))
    # 0    0.10000
    # 1    0.10000
    # 2    0.05500
    # 3    0.02563
    # dtype: float64
    

    【讨论】:

      【解决方案2】:

      不知何故,你需要一个条件。这是一种可能的方式:

      l = pd.Series((float(x.strip('%'))/100 if '%' in x else float(x) for x in mixed))
      print(l)
      
      0    0.10000
      1    0.10000
      2    0.05500
      3    0.02563
      dtype: float64
      

      【讨论】:

        【解决方案3】:

        最简单的解决方案是使用掩码选择条目并批量处理:

        from pandas import Series, to_numeric
        
        mixed = Series(["10%", "0.10", "5.5%", "0.02563"])
        
        # make an empty series with similar shape and dtype float
        converted = Series(index=mixed.index, dtype='float')
        
        # use a mask to select specific entries
        mask = mixed.str.contains("%")
        
        converted.loc[mask] = to_numeric(mixed.loc[mask].str.replace("%", "")) / 100
        converted.loc[~mask] = to_numeric(mixed.loc[~mask])
        
        print(converted)
        # 0    0.10000
        # 1    0.10000
        # 2    0.05500
        # 3    0.02563
        # dtype: float64
        

        【讨论】:

          【解决方案4】:
          mixed = mixed.apply(lambda x: float(x[:-1])/100 if '%' in x else float(x))
          

          输出:

          0    0.10000
          1    0.10000
          2    0.05500
          3    0.02563
          dtype: float64
          

          【讨论】:

            【解决方案5】:

            试试:

            mixed = pd.Series(["10%", "0.10", "5.5%", "0.02563"])
            
            
            mixed = mixed.str.replace("%", "e-02")
            print(pd.to_numeric(mixed))
            

            打印:

            0    0.10000
            1    0.10000
            2    0.05500
            3    0.02563
            dtype: float64
            

            【讨论】:

              【解决方案6】:

              您可以使用其中任何一种

              试试apply

              mixed = pd.Series(["10%","0.10","5.5%","0.02563"])
              
              def percent_to_float(x):
                  if x.endswith("%"):
                      x = x.rstrip("%")
                      return float(x)/100
                  else:
                      return float(x)
              
              cleaned = mixed.apply(lambda x : percent_to_float(x)) 
              
              print(cleaned)
              

              还有str.replace

              mixed = pd.Series(["10%", "0.10", "5.5%", "0.02563"])
              mixed = mixed.str.replace("%", "e-02")
              
              print(pd.to_numeric(mixed))
              

              您也可以使用regex replaceapply

              import re
              
              mixed = pd.Series(["10%","0.10","5.5%","0.02563"])
              
              def percent_to_float(x):
                  return float(re.sub( "%", "e-02", x))
              
              cleaned = mixed.apply(lambda x : percent_to_float(x)) 
              
              print(cleaned)
              

              通过任何方法你都会得到

              0    0.10000
              1    0.10000
              2    0.05500
              3    0.02563
              dtype: float64
              

              【讨论】:

                猜你喜欢
                • 2013-07-16
                • 2023-02-01
                • 2016-10-30
                • 2022-10-23
                • 2021-11-30
                • 1970-01-01
                • 2023-03-31
                • 1970-01-01
                • 2013-02-03
                相关资源
                最近更新 更多