加入pandas中的文件

时间:2015-05-06 12:13:31

标签: pandas

我来自Excel背景,但我喜欢大熊猫,它确实让我更有效率。不幸的是,我可能从Excel中带来了一些不良习惯。我有三个大文件(每个文件在200万到1300万行之间),其中包含可以绑定在一起的交互数据,遗憾的是,没有连接文件的唯一键。我将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')

如您所见,这需要时间。我必须格式化每个日期,然后将它们转换为文本,创建一个添加到文件大小的对象列,并(由于原始数据问题本身)删除重复项,所以我不会意外地膨胀数字。我有更高效的工作流程吗?

1 个答案:

答案 0 :(得分:3)

而不是使用on = 'Unique'

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

您可以将列表列表传递给on关键字参数:

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

Pandas将根据'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
警告:

将CustomerID添加到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'])

没有必要将任何列转换回字符串。