【问题标题】:python: convert numerical data in pandas dataframe to floats in the presence of stringspython:在存在字符串的情况下将pandas数据框中的数字数据转换为浮点数
【发布时间】:2013-11-20 18:09:11
【问题描述】:

我有一个带有“cap”列的 pandas 数据框。此列主要由浮点数组成,但其中包含一些字符串,例如在索引 2 处。

df =
    cap
0    5.2
1    na
2    2.2
3    7.6
4    7.5
5    3.0
...

我从 csv 文件中导入我的数据,如下所示:

df = DataFrame(pd.read_csv(myfile.file))

不幸的是,当我这样做时,“cap”列完全作为字符串导入。我希望将浮点数标识为浮点数,将字符串标识为字符串。尝试使用以下方法进行转换:

df['cap'] = df['cap'].astype(float)

抛出错误:

could not convert string to float: na

有没有办法让所有的数字都变成浮点数,但把 'na' 保留为字符串?

【问题讨论】:

  • 我认为这可能会损害性能。列中的混合类型会强制您使用dtype=object,而您可能会与dtype=float 相处融洽。有一个特殊的“非数字”浮点值 (numpy.nan) 可以很好地指示丢失的数据。还有Pandas understands it very well.
  • 你只需要在read_csv中指定na_values=['na']就可以了,见here
  • 或者您可以使用df.convert_objects(convert_numeric='force') 将非数字强制为nan(在cython 中实现,因此速度非常快)
  • 你考虑接受这个answer

标签: python pandas dataframe


【解决方案1】:

使用 float64 dtype 列(而不是对象)的计算效率更高,因此这通常是首选...它还允许您进行其他计算。因为这是recommended to use NaN for missing data(而不是你自己的占位符,或者None)。

这真的是你想要的答案吗?

In [11]: df.sum()  # all strings
Out[11]: 
cap    5.2na2.27.67.53.0
dtype: object

In [12]: df.apply(lambda f: to_number(f[0]), axis=1).sum()  # floats and 'na' strings
TypeError: unsupported operand type(s) for +: 'float' and 'str'

您应该使用 convert_numeric 强制转换为浮点数:

In [21]: df.convert_objects(convert_numeric=True)
Out[21]: 
   cap
0  5.2
1  NaN
2  2.2
3  7.6
4  7.5
5  3.0

或者通过将“na”附加到被视为 NaN 的值列表中,直接将其作为 csv 读取:

In [22]: pd.read_csv(myfile.file, na_values=['na'])
Out[22]: 
   cap
0  5.2
1  NaN
2  2.2
3  7.6
4  7.5
5  3.0

无论哪种情况,sum(和许多其他 pandas 函数)现在都可以工作:

In [23]: df.sum()
Out[23]:
cap    25.5
dtype: float64

作为Jeff advises:

快速重复 3 次:object==bad, float==good

【讨论】:

    【解决方案2】:

    首先,您导入 CSV 的方式是多余的,而不是这样做:

    df = DataFrame(pd.read_csv(myfile.file))
    

    你可以直接做:

    df = pd.read_csv(myfile.file)
    

    然后转换为浮点数,并将任何不是数字的内容作为NaN:

    df = pd.to_numeric(df, errors='coerce')
    

    【讨论】:

      【解决方案3】:

      这是一个可能的解决方法

      首先定义一个函数,仅在需要时将数字转换为浮点数

       def to_number(s):
          try:
              s1 = float(s)
              return s1
          except ValueError:
              return s
      

      然后你逐行应用它。


      示例:

      给定

       df 
           0
        0  a
        1  2
      

      a2 都是字符串,我们通过以下方式进行转换

      converted = df.apply(lambda f : to_number(f[0]) , axis = 1)  
      
       converted
       0    a
       1    2
      

      直接检查类型:

      type(converted.iloc[0])                                                                                                                             
      str
      
      type(converted.iloc[1])                                                                                                                             
      float
      

      【讨论】:

      • 虽然这可以满足 OP 的要求,但在 imo 中这样做并不是很有用,因为您无法进行任何分析......
      • @AndyHayden,我同意..感谢您发布您的解决方案
      【解决方案4】:

      我在上面尝试了一个替代方案:

      for num, item in enumerate(data['col']):
          try:
              float(item)
          except:
              data['col'][num] = nan
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2019-07-06
        • 1970-01-01
        • 2019-07-10
        相关资源
        最近更新 更多