[英]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.