2017-02-09 177 views
0

在pandas read_csv中,有沒有一種方法來指定例如。 col1,col15,全線?pandas dataframe read_csv,指定列並將整行保留爲一個字符串

我想從一個文本文件中導入約700000行數據,這個文件有帽子'^'作爲分界符,沒有文本限定符,並且回車符爲行分隔符。

從文本文件我需要列1,列15,然後在表/數據框的三列中的整個行。

我已經搜索瞭如何在熊貓中做到這一點,但不知道它足夠好,以獲得邏輯。我可以導入所有26列罰款,但這並不能幫助我的問題。

my_df = pd.read_csv("tablefile.txt", sep="^", lineterminator="\r", low_memory=False) 

或者,我可以用標準的Python把數據插入到表,但這需要約4小時的70萬行。這對我來說太長了。

count_1 = 0 
for line in open('tablefile.txt'): 
    if count_1 > 70: 
     break 
    else: 
     col1id = re.findall('^(\d+)\^', line) 
     col15id = re.findall('^.*\^.*\^(\d+)\^.*\^.*\^.*\^.*\^.*\^.*\^.*\^.*\^.*\^.*\^.*', line) 
     line = line.strip() 

     count_1 = count_1 + 1 

     cur.execute('''INSERT INTO mytable (mycol1id, mycol15id, wholeline) VALUES (?, ?, ?)''', 
     (col1id[0], col15id[0], line,)) 

     conn.commit() 
    print('row count_1=',count_1) 

在大熊貓read_csv,是否有指定例如一種方式。 col1,col15,全線?

如上,col1col15是數字和wholeline是一個字符串

  • 我不想重新導入後的字符串作爲我可能會失去在這個過程中的某些字符。

感謝

編輯: 提交到數據庫中的每一行燃燒時間。

+0

僅使用python時,應該在循環之外編譯一次正則表達式。這一定會加快速度 –

+0

我不明白這是如何工作的,我認爲re.findall(regex,object)在調用re.findall之前需要創建對象。你有一個例子嗎? – CArnold

回答

0

我把conn.commit()上的外部for循環。它將加載時間縮短了幾分鐘,但我猜測它不太安全。

無論如何感謝您的幫助。

1

使用某個準分隔符(在使用&的im下面)全讀爲一個df,然後使用usecols再次讀取並指定列1和列15的索引並將它們相加。

my_df_full = pd.read_csv("tablefile.txt", sep="&", lineterminator="\r", low_memory=False) 
my_df_full.columns = ['full_line'] 

my_df_cols = pd.read_csv("tablefile.txt", sep="^", lineterminator="\r", low_memory=False, usecols=[1,15]) 

my_df_full[['col1', 'col15']] = my_df_cols 
+0

很難找到不在文本中的分隔符,但我會繼續尋找。 – CArnold

+0

@CArnold如果你沒有找到任何分隔符,你可以連接所有的列,有點乏味但應該工作。看到這個:http://stackoverflow.com/questions/19377969/combine-two-columns-of-text-in-dataframe-in-pandas-python。我不知道它是否工作,但你也可以嘗試刪除'low_memory = False'並使用字符串作爲分隔符。 '九月= 「c_arnold_pandas」' –

1

首先,你可以編譯你的正則表達式來避免解析他們的每一行

import re 

reCol1id = re.compile('^(\d+)\^') 
reCol15id = re.compile('^.*\^.*\^(\d+)\^.*\^.*\^.*\^.*\^.*\^.*\^.*\^.*\^.*\^.*\^.*') 

count_1 = 0 
for line in open('tablefile.txt'): 
    if count_1 > 70: 
     break 
    else: 
     col1id = reCol1id.findall(line)[0] 
     col15id = reCol15id.findall(line)[0] 
     line = line.strip() 

     count_1 += 1 

     cur.execute('''INSERT INTO mytable (mycol1id, mycol15id, wholeline) VALUES (?, ?, ?)''', 
     (col1id, col15id, line,)) 

     conn.commit() 
    print('row count_1=',count_1) 
相關問題