【问题标题】:Convert commas decimal separators to dots within a Dataframe将逗号小数分隔符转换为数据框中的点
【发布时间】:2015-10-20 10:45:32
【问题描述】:

我正在使用pandas.read_csv 导入如下所示的 CSV 文件:

df = pd.read_csv(Input, delimiter=";")

CSV 文件示例:

10;01.02.2015 16:58;01.02.2015 16:58;-0.59;0.1;-4.39;NotApplicable;0.79;0.2
11;01.02.2015 16:58;01.02.2015 16:58;-0.57;0.2;-2.87;NotApplicable;0.79;0.21

问题是当我稍后在我的代码中尝试使用这些值时,我得到了这个错误:TypeError: can't multiply sequence by non-int of type 'float'

错误是因为我尝试使用的数字不是用点 (.) 作为小数分隔符而是逗号 (,)。手动将逗号更改为点后,我的程序可以正常工作。

我无法更改输入的格式,因此必须替换 DataFrame 中的逗号才能使我的代码正常工作,我希望 python 无需手动执行此操作。你有什么建议吗?

【问题讨论】:

    标签: python pandas csv delimiter separator


    【解决方案1】:

    pandas.read_csv 有一个 decimal 参数:doc

    即尝试:

    df = pd.read_csv(Input, delimiter=";", decimal=",")
    

    【讨论】:

      【解决方案2】:

      我认为前面提到的在 pandas read_csv 中包含decimal="," 的答案是首选。

      但是,我发现它与 Python 解析引擎不兼容。例如当使用skiprow= 时,read_csv 将回退到这个引擎,因此据我所知,您不能在同一个 read_csv 语句中使用skiprow=decimal=。另外,我还没有真正让decimal= 语句起作用(可能是因为我)

      我过去常常使用列表推导式.replace.astype 来获得相同的结果。这种方法的主要缺点是它需要一次完成一列:

      df = pd.DataFrame({'a': ['120,00', '42,00', '18,00', '23,00'], 
                      'b': ['51,23', '18,45', '28,90', '133,00']})
      
      df['a'] = [x.replace(',', '.') for x in df['a']]
      
      df['a'] = df['a'].astype(float)
      

      现在,a 列将具有浮点型单元格。 b 列仍然包含字符串。

      注意这里使用的.replace 不是pandas 的,而是Python 的内置版本。 Pandas 的版本要求字符串是完全匹配或正则表达式。

      【讨论】:

      • 读取 excel 文件也需要此解决方法,因为 pd.read_excel 没有 decimal 参数。
      • 函数pandas.to_numeric docs to_numeric 可以用来控制转换错误,而不是astype(float)
      【解决方案3】:

      stallasia 的答案看起来是最好的。

      但是,如果您想在已有数据框的情况下更改分隔符,您可以这样做:

      df['a'] = df['a'].str.replace(',', '.').astype(float)
      

      【讨论】:

        【解决方案4】:

        我回答了关于如何使用 Python Pandas 将小数 comma 更改为小数 dot 的问题。

        $ cat test.py 
        import pandas as pd
        df = pd.read_csv("test.csv", quotechar='"', decimal=",")
        df.to_csv("test2.csv", sep=',', encoding='utf-8', quotechar='"', decimal='.')
        

        我们将小数点分隔符中的读数指定为逗号,而输出分隔符指定为点。所以

        $ cat test.csv 
        header,header2
        1,"2,1"
        3,"4,0"
        $ cat test2.csv 
        ,header,header2
        0,1,2.1
        1,3,4.0
        

        您看到分隔符已更改为点的位置。

        【讨论】:

          【解决方案5】:

          感谢您的精彩回答。我只想补充一点,就我而言,仅使用 decimal=',' 不起作用,因为我有 1.450,00 之类的数字(带有千位分隔符),因此 pandas 无法识别它,但传递 thousands='.' 有助于正确读取文件:

          df = pd.read_csv(
              Input, 
              delimiter=";", 
              decimal=","
              thousands="."
          )
          

          【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 2018-06-20
          • 2023-03-28
          • 1970-01-01
          相关资源
          最近更新 更多