gpt4 book ai didi

python - 如何用 pandas 打开德语 csv 文件?

转载 作者:行者123 更新时间:2023-12-02 19:22:20 24 4
gpt4 key购买 nike

问题

使用 pandas 打开德语 csv 文件的最佳方式是什么?

我有一个包含以下列的德语 csv 文件:

  • 数据:日期,格式为“DD.MM.YYYY”
  • 变音符号:带有德语特有特殊字符的德语名字
  • Zahlen:格式为“000.000,00”的数字

我的预期输出是:

            Umlaute      Zahlen
Datum
2020-01-01 Rüdiger 1000000.11
2020-01-02 Günther 12.34
2020-01-03 Jürgen 567.89

下面提供了示例数据(请参阅文件)。


第一次尝试:使用不带参数的 pd.read_csv()

    df = pd.read_csv('german_csv_test.csv')

这会引发UnicodeDecodeError:

UnicodeDecodeError: 'utf-8' codec can't decode byte 0xfc in position 12: invalid start byte

第二次尝试:使用 pd.read_csv 指定编码和分隔

  df = pd.read_csv('german_csv_test.csv', sep=';', encoding='latin1')

这不会引发错误,但它离我想要的输出还很远:

  • 日期是字符串而不是日期时间。
  • 数字不是 float ,而是对象。
  • “Datum”列不是索引。
        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 代表 "character separated values" .

参数thousands='.'decimal=','

此外,大多数欧洲国家/地区使用点来对千位进行分组,并使用逗号来分隔小数。 This great article解释原因。

参数encoding='latin1'

如果您在 Python documentation 中查找德语编码您将看到德语的编解码器“cp273”。它很少被使用。对于西欧,您应该可以使用“latin1”。使用此编解码器受益于 CPython 中的内部优化:

CPython implementation detail: Some common encodings can bypass the codecs lookup machinery to improve performance. These optimization opportunities are only recognized by CPython for a limited set of (case insensitive) aliases: utf-8, utf8, latin-1, latin1, iso-8859-1, iso8859-1, mbcs (Windows only), ascii, us-ascii, utf-16, utf16, utf-32, utf32, and the same using underscores instead of dashes. Using alternative aliases for these encodings may result in slower execution.

要进一步阅读,请查找 this SO postJoel Spolsky's blog .

参数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 操作,并且您会认为“这真是一团糟。

有多种方法可以清理数据框。但为什么不使用内置转换器呢?如果您为数据帧的每一列定义了dtypesconverters,您就不必回头(愤怒地)。调用 pd.read_csv() 后,您就站稳了脚跟。

请注意,转换器仅接受函数。这就是我在转换器中使用 lambda 函数的原因。否则我无法指定格式参数。

documentation 中了解有关转换器的更多信息并在 this SO post

参数index_col='Datum'

这只是定义索引列。它很方便,因为替代的 df = df.set_index('Datum') 不太漂亮。此外,它还有助于 - 像转换器一样 - 将输入 block 与数据处理分开。

关于python - 如何用 pandas 打开德语 csv 文件?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/62872697/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com