我正在讀取 CSV 數據以用作 pandas 數據框,但 CSV 似乎不遵循任何理智的約定(除了用作;分隔符,每個人都應該......)。看來唯一的目標是讓它們在文本編輯器中打開時看起來不錯以下是一些示例(設置為變量,以便它們可用于讀者示例):ex1="""Type: Some MetadataUser: More MetadataData:01.10.1939 00:00:00 ; 1,1 ; 01.12.1939 00:00:00 ; 1 ; 01.01.1940 00:00:00 ; 10 ; """好的,小數逗號(簡單),分號分隔符(簡單),dayfirst(簡單)和一堆元數據(skiprows,也簡單)。ts = pd.read_csv(io.StringIO(ex1), skiprows=4, decimal=',', sep=';', index_col=0, usecols=[0,1], dayfirst=True, parse_dates=True, names=['date', 'val'])print(ts結果是一個很好的數據框 valdate1939-10-01 1.11939-12-01 1.01940-01-01 10.0andts.index是一個很好的DatetimeIndexandtype(ts.val[0])是一個numpy.float64,因為它應該是這樣。但讓我們介紹一種創造性的標記方式NaN:ex2="""Type: Some MetadataUser: More MetadataData:01.10.1939 00:00:00 ; 1,1; 01.12.1939 00:00:00 ; N? ; 01.01.1940 00:00:00 ; 10 ; """上面的代碼ts=read_csv...仍然可以正常工作,但不會出現錯誤,但N?會破壞val列并將其轉換為字符串。但是當我將其更改為ts = pd.read_csv(io.StringIO(ex2), skiprows=4, decimal=',', sep=';', index_col=0, usecols=[0,1], dayfirst=True, parse_dates=True, names=['date', 'val'], na_values='N?')使用na_values,整個事情都會失敗。print(ts) valdate1939-10-01 1,11939-12-01 N?1940-01-01 10它不僅不接受N?as NaN,還將所有vals 轉換為字符串,從而忽略小數逗號并保留尾隨空格。ts.val[0]是現在' 1,1',所以簡單ts.val = ts.val.astype(float)的當然失敗了。我做錯了什么na_values='N?'?為什么它也會打破decimal','并添加空格?看起來skipinitialspace=True應該有幫助,但當然N?仍然打破了val專欄。 sep='\s*[;]s*'看起來很有希望,并且ts = pd.read_csv(io.StringIO(ex2), skiprows=4, decimal=',' ,sep='\s*[;]s*', index_col=0, usecols=[0,1], dayfirst=True, parse_dates=True, names=['date', 'val'], na_values='N?')(注意小數點?。?,但現在我遇到了奇怪的情況,它確實替換了逗號,但ts.val[0]現在又是一個字符串,并且仍然有尾隨空格(' 1.1')。那么我如何讀取這些無聊的文件呢?我當前使用的解決方法是使用純Python讀取CSV(無論如何我都必須讀取標題(實際文件中的40行))并將其寫入正確的CSV,以便用pandas讀?。旱菍τ趲浊€ CSV 文件,大小達到一兆字節,這并不是一個真正的最佳解決方案,所以我想N?在導入中解決這個問題。
1 回答

狐的傳說
TA貢獻1804條經驗 獲得超3個贊
您的sep指定錯誤(它s*以 而不是 結尾\s*,這意味著它正在尋找 0 到無限個s字符之間)。這就是為什么您只捕獲前導空格而不捕獲 后的尾隨空格;。順便說一句,這也干擾了 (1),因為您試圖替換'N?'但值為' N?'。sep='\s*\;\s*'代替使用。
您將來可以做的一件事是自己打印出有問題的值,以確保它們包含他們認為您包含的內容,例如ts.iloc[1].val。
另外,如果NaNunicode 中的值有問題,您可以在解析之前將其剝離:
csv = io.StringIO(ex2.replace(u'N\xc4', '[MISSING]'))
ts = pd.read_csv(csv,
skiprows=4, decimal=',', index_col=0, usecols=[0,1],
dayfirst=True, parse_dates=True, names=['date', 'val'],
na_values='[MISSING]', sep='\s*\;\s*')
...這會給...
val
date
1939-10-01 1.1
1939-12-01 NaN
1940-01-01 10.0
添加回答
舉報
0/150
提交
取消