簡體   English   中英

熊貓 read_csv dtype 前導零

[英]Pandas read_csv dtype leading zeros

所以我正在讀取來自 NOAA 的站代碼 csv 文件,它看起來像這樣:

"USAF","WBAN","STATION NAME","CTRY","FIPS","STATE","CALL","LAT","LON","ELEV(.1M)","BEGIN","END"
"006852","99999","SENT","SW","SZ","","","+46817","+010350","+14200","",""
"007005","99999","CWOS 07005","","","","","-99999","-999999","-99999","20120127","20120127"

前兩列包含氣象站的代碼,有時它們有前導零。 當熊貓在不指定 dtype 的情況下導入它們時,它們會變成整數。 這並不是什么大問題,因為我可以遍歷數據幀索引並將它們替換為"%06d" % i因為它們總是六位數,但你知道......這是懶人的方式。

使用以下代碼獲取 csv:

file = urllib.urlopen(r"ftp://ftp.ncdc.noaa.gov/pub/data/inventories/ISH-HISTORY.CSV")
output = open('Station Codes.csv','wb')
output.write(file.read())
output.close()

這一切都很好,但是當我去嘗試使用它閱讀它時:

import pandas as pd
df = pd.io.parsers.read_csv("Station Codes.csv",dtype={'USAF': np.str, 'WBAN': np.str})

要么

import pandas as pd
df = pd.io.parsers.read_csv("Station Codes.csv",dtype={'USAF': str, 'WBAN': str})

我收到一條令人討厭的錯誤消息:

File "C:\Python27\lib\site-packages\pandas-0.11.0-py2.7-win32.egg\pandas\io\parsers.py", line 401, in parser
_f
    return _read(filepath_or_buffer, kwds)
  File "C:\Python27\lib\site-packages\pandas-0.11.0-py2.7-win32.egg\pandas\io\parsers.py", line 216, in _read
    return parser.read()
  File "C:\Python27\lib\site-packages\pandas-0.11.0-py2.7-win32.egg\pandas\io\parsers.py", line 633, in read
    ret = self._engine.read(nrows)
  File "C:\Python27\lib\site-packages\pandas-0.11.0-py2.7-win32.egg\pandas\io\parsers.py", line 957, in read
    data = self._reader.read(nrows)
  File "parser.pyx", line 654, in pandas._parser.TextReader.read (pandas\src\parser.c:5931)
  File "parser.pyx", line 676, in pandas._parser.TextReader._read_low_memory (pandas\src\parser.c:6148)
  File "parser.pyx", line 752, in pandas._parser.TextReader._read_rows (pandas\src\parser.c:6962)
  File "parser.pyx", line 837, in pandas._parser.TextReader._convert_column_data (pandas\src\parser.c:7898)
  File "parser.pyx", line 887, in pandas._parser.TextReader._convert_tokens (pandas\src\parser.c:8483)
  File "parser.pyx", line 953, in pandas._parser.TextReader._convert_with_dtype (pandas\src\parser.c:9535)
  File "parser.pyx", line 1283, in pandas._parser._to_fw_string (pandas\src\parser.c:14616)
TypeError: data type not understood

這是一個非常大的 csv(31k 行),所以也許這與它有關?

這是pandas dtype guessing的問題。

Pandas 看到數字並猜測您希望它是數字。

為了讓 Pandas 不會懷疑你的意圖,你應該設置你想要的 dtype: object

pd.read_csv('filename.csv', dtype={'leading_zero_column_name': object})

會做的伎倆

更新,因為它可以幫助其他人:

要將所有列都作為 str,可以這樣做(來自評論):

pd.read_csv('sample.csv', dtype = str)

要將大多數或選擇性列作為 str,可以這樣做:

# lst of column names which needs to be string
lst_str_cols = ['prefix', 'serial']
# use dictionary comprehension to make dict of dtypes
dict_dtypes = {x : 'str'  for x in lst_str_cols}
# use dict on dtypes
pd.read_csv('sample.csv', dtype=dict_dtypes)

在解析帶有序列號的文件時,這個問題讓我很頭疼。 由於未知原因,00794 和 000794 是兩個不同的序列號。 我最終想出了

converters = {'serial_number': str}

如果您不希望它成為對象,則看起來您必須指定字符串的長度。
例如:

dtype={'USAF': '|S6'}

我找不到這方面的參考資料,但我似乎記得 Wes 討論過這個問題(也許是在一次談話中)。 他建議 numpy 不允許“適當的”可變長度字符串(請參閱此問題/答案),並且使用最大長度來填充數組通常會導致非常低的空間效率(即使字符串很短,它也會使用與最長字符串一樣多的空間)。

正如@Wes 指出的那樣,這也是一種情況:

dtype={'USAF': object}

效果也一樣。

您可以將函數字典傳遞給converters ,其中鍵是數字列索引。 因此,如果您不知道您的列名是什么,您可以這樣做(假設您的列數少於 100)。

pd.read_csv('some_file.csv', converters={i: str for i in range(100)})

使用 Pandas 1,如何:

df.read_csv(..., dtype={"my_confusing_col": "string"})

請注意,將使用列pd.NA string ,該stringpd.NA用於任何缺失值。 當然,所有前導零都將被保留。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM