2017-04-10 70 views
0

我想:最快的方式功能/字典應用到每一個元素的熊貓數據幀上選定列

  • 閱讀數百製表符分隔的文件到大熊貓數據幀
  • 決定是否申請基於功能上FileNo
  • 應用函數到每個元件上選定列
  • 追加並連接所有DataFrames到單個幀

示例文件:

ID FileNo Name A1 A2 A3 
1 0  John a-b b-a a-a 
2 0 Carol b-b a-b a-b 
[...] 
500 0 Steve a-a b-b  a-b 
501 0 Jack  b-a b-a  a-b 

真尺寸爲每個文件:2000x15000

功能:反向的字符串。

flip_over = lambda x: x[::-1] 
or 
my_dict = {'a-b':'b-a', 'a-a':'a-a', 'b-b':'b-b', 'b-a':'a-b'} 
map(my_dict) 

我目前有:

whether_to_flip = [7,15,23,36,48,85] 
frames = [] 
base_path = "/home/user/file_" 

for i in range(0, 100): 
    path = base_path + str(i) + ".tsv" 
    df = pd.read_csv(path, sep="\t", header=None) 
    df['FileNo'] = str(i) 
    if i in whether_to_flip: 
      for j in range(3,6): 
       df[j] = df[j].map(my_dict) 
    frames.append(df) 

combined = pd.concat(frames, axis=0, ignore_index=True) 

這是目前正在小時才能完成讀取和處理,和我打的內存限制,當我需要增加的文件數量閱讀。

我希望有任何幫助來改善此代碼。特別是,

  • 這是應用函數的最好/最快的方式嗎?
  • 這是追加和連接多個DataFrames的最佳方式嗎?

謝謝。

回答

0

首先,我想你應該明白你在閱讀csv與時間倒置字符串的過程中失去了多少時間。

我可以看到一對夫婦的事情,可以加快程序:

避免過度列循環

您可以使用replace和my_dict:(ref)

if i in whether_to_flip: 
    df = df.replace(my_dict) 
# df = df.replace({'A1' : my_dict, 'A2' : my_dict, 'A3' : my_dict) 

我認爲這應該會顯着改善性能。

列表理解,以避免.append

這可以使語法更麻煩一點,但可以有some微小的效率增益

def do_path(x): 
    return base_path + str(i) + ".csv" 



[ pd.read_csv(do_path(i), sep="\t", header=None).assign(FileNo = str(i)) if i not in whether_to_flip 
    else pd.read_csv(do_path(i), sep="\t", header=None).assign(FileNo = str(i)).map(my_dict) 
    for i in range(0, 100)] 
+0

感謝您的評論!我擔心使用替換是它可能遭受傳遞替換覆蓋。 dict = {'a-b':'b-a','b-a':'a-b'}。當它在一個單元格上循環並看到'a-b'時,它將用'b-a'代替它,但是,在停留在同一個單元格中時,它可能會應用第二個鍵將單元格還原回原始值。這就是爲什麼我認爲我可能會明確使用列名並按列進行映射,而不是讓迭代應用替換。也許我錯了嗎? – user3131944

+0

回覆:追加部分:我想知道是否最好將文件連接成一個大文件,將它讀入熊貓數據框,然後處理它(而不是讀取每個文件,進程和連接)。 – user3131944

+0

時間:僅讀取10個文件時,無反轉需要12.67(time.clock()),反轉需要33.28。 – user3131944