2016-08-02 33 views
3

我正在嘗試使用pandas read_csv讀取大文件(〜8Gb)。在數據的其中一列中,有時會列出一個包含逗號但它通過花括號例如使用read_csv引起的額外逗號導致數據幀中出現太多

「label1的」, 「LABEL2」, 「LABEL3」, 「label4」, 「label5」

「{A1}」, 「2」, 「」,「假封閉「,」{「apple」:false,「pear」:false,「banana」:null}

因此,當讀取這些特定行時,出現錯誤「Error tokenizing data。C error:Expected 37第35行的田地,看到42「。我找到了this解決方案,它說要添加 sep =「,(?![^ {* *))」到read_csv參數中,這些參數正確地分割數據。但是,數據現在包含每個條目的引號(這在我添加sep參數之前沒有發生)。

的數據現在看起來是這樣的:

「LABEL1」 「LABEL2」 「LABEL3」 「label4」 「label5」

「{A1}」 「2」 「」 「假」,「{ 「apple」:false,「pear」:false,「banana」:null}「

意思是我不能在數字數據上使用例如.describe()等,因爲它們仍然是字符串。

有沒有人知道在沒有引號的情況下閱讀它的方式,但是仍然會將數據分裂到哪裏?

對Python很新穎,所以如果有明顯的解決方案,我們表示歉意。

serialdev找到了解決刪除「秒,但該數據列的對象,而不是我期望/想要的,例如整數值不被視爲整數。

的數據需要在被拆分「,」明確地(包括「s」),有沒有一種方式說明在read_csv參數中?

謝謝!

回答

1

要在數據結構中讀取您指定,其中最後元素是未知長度。

「{A1}」, 「2」, 「」, 「假」, 「{ 」蘋果「:假的, 」梨「:假的, 」香蕉「:空}」

「{A1} 「,」2「,」「,」False「,」{「apple」:false,「pear」:false,「banana」:null,「orange」:「true」} 一個使用負向前瞻式斷言的正則表達式。這將使您能夠在沒有緊跟空格的情況下分開','。

df = pd.read_csv('my_file.csv', sep='[,](?!\s)', engine='python', thousands='"') 

print df 

     0 1 2  3             4 
0 "{A1}" 2 NaN "False" "{ "apple" : false, "pear" : false, "banana" :... 
1 "{A1}" 2 NaN "False" "{ "apple" : false, "pear" : false, "banana" :... 

指定千位分隔符作爲引用是一個hackie解析字段的方式包含引用的整數到正確的數據類型。您可以使用轉換器來獲得相同的結果,如果您需要它,也可以從字符串中刪除引號,並將「True」或「False」轉換爲布爾值。

+0

謝謝你的回答 - 我接受了,因爲它做了我想要的東西一條線。 :) –

0

這取決於你的文件。您是否在單元格中查看您的數據是否有逗號?如果你有這樣的香蕉:水果,熱帶,可食用等等,你會得到這樣的錯誤。基本解決方案之一是刪除文件中的所有逗號。或者,如果你能讀它,你可以刪除特殊字符:

>>>df 
       Banana 
0 Hello, Salut, Salom 
1    Bonjour 


>>>df['Banana'] = df['Banana'].str.replace(',','') 
>>>df 
       Banana 
0 Hello Salut Salom 
1   Bonjour 
+0

問題是數據框中的每個條目都被引號包圍。在我的問題中,它顯示了一個例子: {A1}「」2「」「」False「」{「apple」:false,「pear」:false,「banana」:null}「將是一行數據, 2「是一個字符串,而不是一個整數,我想這樣的數據 - 逗號不是一個問題 - 只是在所有內容都沒有引號的情況下 –

1

將這項工作,因爲你有你需要的所有數據:

.map(lambda x: x.lstrip('\"').rstrip('\"')) 

所以,簡單地收拾"所有出現事後

編輯與例如:

mydata = [{'"first_name"' : '"bill', 'age': '"75"'}, 
      {'"first_name"' : '"bob', 'age': '"7"'}, 
      {'"first_name"' : '"ben', 'age': '"77"'}] 
IN: df = pd.DataFrame(mydata) 
OUT: 
    "first_name" age 
0  "bill "75" 
1   "bob "7" 
2   "ben "77" 

IN: df['"first_name"'] = df['"first_name"'].map(lambda x: x.lstrip('\"').rstrip('\"')) 
OUT: 
0 bill 
1  bob 
2  ben 
Name: "first_name", dtype: object 

使用此塞克NCE選擇列後,這是不理想,但會完成這項工作:

df['col'].apply(lambda x: pd.to_numeric(x, errors='ignore')) 

或者乾脆:

df[['col2','col3']] = df[['col2','col3']].apply(pd.to_numeric) 
+0

不,它沒有工作,因爲某些原因.. I made一個快速演示: 進口csv 與開放('名稱。csv','w')as csvfile: fieldnames = [''first_name'',''age''] writer = csv.DictWriter(csvfile,fieldnames = fieldnames) writer.writeheader() writer.writerow {''first_name''''Bill'',''age'':'「7」'}) writer.writerow({''first_name'''''Bob''''age'': ''8'')) df = pd.read_csv('names.csv') Writer.writerow({'「first_name」':'「Ben」','「age」':'「9」'}) ') df.replace(''','') 如果你跑進去,「s仍然會在那裏。你還有其他建議嗎? 謝謝! –

+0

感謝您的編輯:) 我發現df = df.applymap(lambda x:x.lstrip('\'')。rstrip('\''))一次將它應用到整個數據框架中,所以刪除但是,當你看到df [''age''] .dtype時,它說它是一個對象,當它是一個整數時,認爲最好是在「,」處分割或者考慮更改數據源。 –

+0

是的,這只是刪除「s」,之後你應該定義所需的dtypes,我已經爲它添加了進一步的編輯。考慮接受答案,如果解決了所有問題 – SerialDev

1

.map(lambda x: x.lstrip('\"').rstrip('\"')) 

您可以使用此模式後更改Dtypes

如果需要從列中刪除",請使用矢量化函數str.strip

import pandas as pd 

mydata = [{'"first_name"': '"Bill"', '"age"': '"7"'}, 
      {'"first_name"': '"Bob"', '"age"': '"8"'}, 
      {'"first_name"': '"Ben"', '"age"': '"9"'}] 
df = pd.DataFrame(mydata) 
print (df) 
    "age" "first_name" 
0 "7"  "Bill" 
1 "8"  "Bob" 
2 "9"  "Ben" 

df['"first_name"'] = df['"first_name"'].str.strip('"') 
print (df) 
    "age" "first_name" 
0 "7"   Bill 
1 "8"   Bob 
2 "9"   Ben 

如果需要應用功能str.strip()所有列,請使用:

df = pd.concat([df[col].str.strip('"') for col in df], axis=1) 
df.columns = df.columns.str.strip('"') 
print (df) 
    age first_name 
0 7  Bill 
1 8  Bob 
2 9  Ben 

時序

mydata = [{'"first_name"': '"Bill"', '"age"': '"7"'}, 
      {'"first_name"': '"Bob"', '"age"': '"8"'}, 
      {'"first_name"': '"Ben"', '"age"': '"9"'}] 
df = pd.DataFrame(mydata) 
df = pd.concat([df]*3, axis=1) 
df.columns = ['"first_name1"','"age1"','"first_name2"','"age2"','"first_name3"','"age3"'] 
#create sample [300000 rows x 6 columns] 
df = pd.concat([df]*100000).reset_index(drop=True) 
df1,df2 = df.copy(),df.copy() 

def a(df): 
    df.columns = df.columns.str.strip('"') 
    df['age1'] = df['age1'].str.strip('"') 
    df['first_name1'] = df['first_name1'].str.strip('"') 
    df['age2'] = df['age2'].str.strip('"') 
    df['first_name2'] = df['first_name2'].str.strip('"') 
    df['age3'] = df['age3'].str.strip('"') 
    df['first_name3'] = df['first_name3'].str.strip('"') 
    return df 

def b(df): 
    #apply str function to all columns in dataframe 
    df = pd.concat([df[col].str.strip('"') for col in df], axis=1) 
    df.columns = df.columns.str.strip('"') 
    return df 

def c(df): 
    #apply str function to all columns in dataframe 
    df = df.applymap(lambda x: x.lstrip('\"').rstrip('\"')) 
    df.columns = df.columns.str.strip('"') 
    return df 

print (a(df)) 
print (b(df1)) 
print (c(df2)) 
In [135]: %timeit (a(df)) 
1 loop, best of 3: 635 ms per loop 

In [136]: %timeit (b(df1)) 
1 loop, best of 3: 728 ms per loop 

In [137]: %timeit (c(df2)) 
1 loop, best of 3: 1.21 s per loop 
+0

如果需要轉換爲整數的某一列,請使用['astype'](http://pandas.pydata.org/pandas-docs/stable/generated/pandas.Series.astype.html) - 'df [' ('''')。astype(int)' – jezrael

+0

非常感謝你:) –