2015-05-06 36 views
0

我來自Excel背景,但我愛熊貓,它確實讓我更有效率。不幸的是,我可能會從Excel中帶走一些不良習慣。我有三個大文件(每個在兩百萬到一千三百萬行之間),其中包含有關可能綁定在一起的交互的數據,遺憾的是,沒有用於連接文件的唯一鍵。我從字面上將(Excel公式)3個字段拼接成所有三個文件中的一個新列。加入熊貓檔案

這三列存在於每個文件中,我將它們組合在一起(其他字段將像是一個文件上的交互原因,另一個文件上的分數以及第三個文件上的一些其他數據,我希望一起回綁到一定AGENTID):

Date | CustomerID | AgentID 

修改我的日期格式是對每個文件統一:

df[Date] = pd.to_datetime(df['Date'], coerce = True) 
df[Date] = df[Date].apply(lambda x:x.date().strftime('%Y-%m-%d')) 

然後,我創建一個唯一的列(當然,獨一無二的,因爲我可以得到它有時候是同一個客戶與同一個代理進行交互在同一天,但這應該是相當少見):

df[Unique] = df[Date].astype(str) + df[CustomerID].astype(str) + df[AgentID].astype(str) 

我做DF2,然後同樣的步驟:

combined = pd.merge(df, df2, how = 'left', on = 'Unique') 

我通常發送到一個新的CSV在萬一死機,gzip的它,然後再次讀取,並再次使用第三個文件執行相同的過程。

final = pd.merge(combined, df2, how = 'left', on = 'Unique') 

正如你所看到的,這需要時間。我必須格式化每個日期,然後將它們轉換爲文本,創建一個添加到文件大小的對象列,以及(由於原始數據問題本身)刪除重複項,所以我不會意外膨脹數字。我有沒有更高效的工作流程?

回答

3

而不是使用on = 'Unique'的:

combined = pd.merge(df, df2, how = 'left', on = 'Unique') 

你可以通過列的列表中on關鍵字參數:基於價值從'Date', 'CustomerID', 'AgentID'三重

combined = pd.merge(df, df2, how='left', on=['Date', 'CustomerID', 'AgentID']) 

大熊貓將正確合併行列。這更安全(見下文),比構建Unique列更簡單。


例如,

import pandas as pd 
import numpy as np 
np.random.seed(2015) 

df = pd.DataFrame({'Date': pd.to_datetime(['2000-1-1','2000-1-1','2000-1-2']), 
        'CustomerID':[1,1,2], 
        'AgentID':[10,10,11]}) 

df2 = df.copy() 
df3 = df.copy() 
L = len(df) 
df['ABC'] = np.random.choice(list('ABC'), L) 
df2['DEF'] = np.random.choice(list('DEF'), L) 
df3['GHI'] = np.random.choice(list('GHI'), L) 
df2 = df2.iloc[[0,2]] 

combined = df 
for x in [df2, df3]: 
    combined = pd.merge(combined, x, how='left', on=['Date','CustomerID', 'AgentID']) 

產生

In [200]: combined 
Out[200]: 
    AgentID CustomerID  Date ABC DEF GHI 
0  10   1 2000-1-1 C F H 
1  10   1 2000-1-1 C F G 
2  10   1 2000-1-1 A F H 
3  10   1 2000-1-1 A F G 
4  11   2 2000-1-2 A F I 

一個警告:

添加在客戶到AGENTID創建一個唯一的ID可以是有問題的 - 特別是如果沒有固定寬度格式。

例如,如果CustomerID = '12'AgentID = '34'然後(忽略,因爲它不具有固定的寬度,其不會產生問題的時間)Unique將是 '1234'。但是如果CustomerID = '1'AgentID = '234'Unique將 再次等於'1234'。所以Unique ID可能會混合完全不同的 客戶/代理對。


PS。這是解析日期字符串成日期狀物體

df['Date'] = pd.to_datetime(df['Date'], coerce=True) 

注意一個好主意,如果你使用

combined = pd.merge(combined, x, how='left', on=['Date','CustomerID', 'AgentID']) 

沒有必要對任何列轉換回字符串。

+0

太棒了。工作。非常感謝。我回去編輯了所有的加入文件。 – trench