Pandas:读取带引号的值,逗号作为小数点分隔符,句点作为数字分组符号的csv

Pandas: Read csv with quoted values, comma as decimal separator, and period as digit grouping symbol

更新:最初发布问题时,我没有意识到 . 在某些条目中用作数字分组符号。但是,此信息对于解决问题至关重要。这是原始问题:

我目前正在尝试在 pandas 中导入一个格式不太完美的 csv 文件,因为包括数字在内的所有值都被引用了。格式如下所示:

Date;Type;Amount;Currency;Category;Person;Account;Counter Account;Group;Note
"19.02.17";"Expenses";"-36,37";"EUR";"Groceries";"";"Bank account";"";"";""

现在,我尝试使用以下命令导入它:

import pandas

dtypes = {"Type":"string", "Amount": "float"}
table = pandas.read_csv("data.csv", delimiter = ";", decimal = ",", parse_dates = ["Date"], dtype = dtypes, quoting = 3)

所以我基本上一直试图告诉 pandas 小数点分隔符是逗号,字段分隔符是分号,“金额”列应该解析为浮点数。但是,尝试解析文件时,我仍然收到错误消息:

ValueError: could not convert string to float: '689,15'"

我认为引号和逗号小数点分隔符的组合对于 pandas 来说有点太多了,尽管我认为我在技术上已经为它提供了它需要的所有信息。

该文件是从第三方程序导出的,所以很遗憾,我对格式没有影响。 有谁知道如何让 pandas 吞下这个?

奖励问题:如果我在没有提供明确数据类型的情况下读取此文件,我不会像我预期的那样得到任何类型为“string”的列,而是使用“object”。这是为什么?

更新:虽然这个答案仍然有效,但有一个更简单的解决方案。我最初没有意识到某些条目使用 . 作为数字分组符号,因此造成混淆。

好的,我找到了一种使用 converters 参数传递执行转换的 lambda 的方法。到目前为止我找不到更简单的解决方案。

toFloat = lambda x: float(x.replace(".", "").replace(",", "."))
table = pandas.read_csv("data.csv", delimiter = ";", decimal = ",", parse_dates = ["Date"], converters = {"Amount": toFloat})

lambda toFloat 接受一个字符串,删除所有出现的 . 字符(用作数字分组符号),用 . 替换所有出现的 ,然后将生成的字符串转换为浮点数。然后,此 lambda 作为“金额”列的转换器传递给 read_csv 函数。可能现在 decimal 参数也是可以消耗的。

我暂时保留这个问题,看看是否有人能提出更简单的解决方案。

那个呢?

import pandas

table = pandas.read_csv("data.csv", sep=";", decimal=",")

print(table["Amount"][0])  # -36.37
print(type(table["Amount"][0]))   # <class 'numpy.float64'>
print(table["Amount"][0] + 36.37)  # 0.0

Pandas自动检测一个数字并将其转换为numpy.float64.


编辑:

正如@bweber 所发现的,data.csv 中的某些值包含超过 3 个数字,并使用了数字分组符号 '.'。为了将字符串转换为整数,必须将使用的符号传递给 read_csv() 方法:

table = pandas.read_csv("data.csv", sep=";", decimal=",", thousands='.')