[英]How to open a German csv file with pandas?
用 pandas 打开德国 csv 文件的最佳方法是什么?
我有一个德国 csv 文件,其中包含以下列:
我预期的 output 是:
Umlaute Zahlen
Datum
2020-01-01 Rüdiger 1000000.11
2020-01-02 Günther 12.34
2020-01-03 Jürgen 567.89
下面提供了示例数据(见文件)。
df = pd.read_csv('german_csv_test.csv')
这会引发UnicodeDecodeError
:
UnicodeDecodeError: 'utf-8' codec can't decode byte 0xfc in position 12: invalid start byte
df = pd.read_csv('german_csv_test.csv', sep=';', encoding='latin1')
这不会引发错误,但与我想要的 output 相差甚远:
Datum Umlaute Zahlen
0 01.01.2020 Rüdiger 1.000.000,11
1 02.01.2020 Günther 12,34
2 03.01.2020 Jürgen 567,89
df = pd.read_csv('german_csv_test.csv', sep=';', encoding='latin1')
df['Datum'] = pd.to_datetime(df['Datum'])
df = df.set_index('Datum')
df['Zahlen'] = pd.to_numeric(df['Zahlen'])
现在,我有四行代码,但它仍然不起作用。 最后一行抛出错误ValueError: Unable to parse string " 1.000.000,11 " at position 0
。 如果我将最后一行注释掉,它会起作用。 但是日期仍然是错误的,因为日期和月份被交换了。
Umlaute Zahlen
Datum
2020-01-01 Rüdiger 1.000.000,11
2020-02-01 Günther 12,34
2020-03-01 Jürgen 567,89
我的文件german_csv_test.csv
看起来像这样:
Datum;Umlaute;Zahlen
01.01.2020;Rüdiger; 1.000.000,11
02.01.2020;Günther; 12,34
03.01.2020;Jürgen; 567,89
它被编码为“cp1252”。 我使用“CSV (MS-DOS)”选项将它保存在 Windows 上。
converters = {'Datum': lambda x: pd.to_datetime(x, format='%d.%m.%Y')}
df1 = pd.read_csv('german_csv_test.csv', sep=';', thousands='.', decimal=',', encoding='latin1',
converters=converters, index_col='Datum')
德国 csv 文件很棘手,因为它们乍一看还不错,但数据类型都错误,月份和日期之间的切换可能会令人沮丧。 以上参数适用于各种欧洲 csv 文件。 下面我将解释每个参数。
sep=';'
几乎所有德国 csv 文件都使用分号 ';' 作为分离字符。 这适用于大多数欧洲国家。 您可能会认为这是错误的,因为 csv 的意思是“逗号分隔值”。 但这不是关于对与错,而是关于惯例。 您可以说 csv 代表“字符分隔值” 。
thousands='.'
和decimal=','
此外,大多数欧洲国家/地区使用点对千位进行分组,并使用逗号分隔小数。 这篇很棒的文章解释了原因。
encoding='latin1'
如果您在Python 文档中查找德语编码,您将看到德语的编解码器“cp273”。 它很少使用。 西欧的“latin1”应该没问题。 使用此编解码器受益于 CPython 中的内部优化:
CPython 实现细节:一些常见的编码可以绕过编解码器查找机制来提高性能。 这些优化机会仅被 CPython 识别为一组有限的(不区分大小写)别名:utf-8、utf8、latin-1、latin1、iso-8859-1、iso8859-1、mbcs(仅限 Windows)、ascii、us-ascii , utf-16, utf16, utf-32, utf32 和相同的使用下划线而不是破折号。 对这些编码使用替代别名可能会导致执行速度变慢。
如需进一步阅读,请查看此 SO 帖子和Joel Spolsky 的博客。
converters=converters
大多数 pandas 用户都低估了转换器。 它看起来像一个简单问题的复杂解决方案。 读取文件后为什么不使用pd.to_datetime()
? 您希望将输入与处理数据分开(参见IPO model )。
我已经多次看到(并写过)这样的事情:
df = pd.read_csv('test.csv')
df['Revenue'] = df['Price'] * df['Quantity'] # I don't have to clean up all columns. I just need the revenue.
(...) # Some other code
# Plotting revenue
df['Revenue'] = df['Revenue'] / 1000
df['Date'] = pd.to_datetime(df['Date']) # Oh, the dates are still strings. I can fix this easily before plotting.
在下一次迭代中,您可以将pd.to_datetime()
向上移动。 但也许不是。 这可能会导致一些意想不到的行为。 编写此类代码两个月后,您只看到一长串非结构化的 pandas 操作,您会认为“这是一团糟。 ”
有几种方法可以清洁您的 dataframe。 但是为什么不使用内置转换器呢? 如果您为 dataframe 的每一列定义dtypes
和converters
,您不必回头(愤怒地)。 调用pd.read_csv()
后,您站在了坚实的基础上。
请注意,转换器仅接受函数。 这就是我在转换器中使用 lambda function 的原因。 否则我无法指定格式参数。
index_col='Datum'
这只是定义了索引列。 这很方便,因为替代df = df.set_index('Datum')
不是那么漂亮。 此外,它有助于 - 像转换器一样 - 将输入块与数据处理分开。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.