匹配具有不同日期范围和不同长度的两个数据集

时间:2014-10-24 13:10:23

标签: python pandas matching

我有两个具有不同日期格式和长度的csv文件。

首先,我加载这两个文件:

frameA = pd.read_csv("fileA.csv", dtype=str, delimiter=";", skiprows = None)

文件A有102216行x 3列,以01.07.2012 00:00结尾。日期和时间在一列中。头看起来像这样:

Date                 Buy     Sell
0  01.08.2009 00:15    0       0
1  01.08.2009 00:30    0       0
2  01.08.2009 00:45    0       0
3  01.08.2009 01:00    0       0
4  01.08.2009 01:15    0       0

frameB = pd.read_csv("fileB.csv", dtype=str, delimiter=";", skiprows = None)

文件B有92762行x 4列,以22.07.2012 00:00结尾。日期和时间单独。头看起来像这样:

        Date    Time         Buy           Sell
0  01.08.2009   01:00          0              0
1  01.08.2009   02:00          0              0
2  01.08.2009   03:00          0              0
3  01.08.2009   04:00          0             10
4  01.08.2009   05:00          0             32

我如何匹配这些数据:

                     Buy A   Sell A   Buy B   Sell B
0  01.08.2009 00:15    0       0       0       0
1  01.08.2009 00:30    0       0       0       0

两者都必须以相同的日期开始和结束,频率必须为15分钟。

我该怎么做?我应该先做什么?

2 个答案:

答案 0 :(得分:1)

好的,首先要确保两个df的日期时间都是第一个df的dtypes:

frameA = pd.read_csv("fileA.csv", dtype=str, delimiter=";", skiprows = None, parse_dates=['Date'])

和另一个df:

frameB = pd.read_csv("fileB.csv", dtype=str, delimiter=";", skiprows = None, parse_dates=[['Date','Time']])

现在我会重置第一个df的分钟值,如下所示:

In [149]:

df['Date'] = df['Date'].apply(lambda x: x.replace(minute=0))
df
Out[149]:
                     Date Buy Sell
index                             
0     2009-01-08 04:00:00   0    0
1     2009-01-08 04:00:00   0    0
2     2009-01-08 04:00:00   0    0
3     2009-01-08 05:00:00   0    0
4     2009-01-08 05:00:00   0    0

现在我们可以合并dfs:

In [150]:

merged = df.merge(df1, left_on=['Date'], right_on=['Date_Time'], how='left',suffixes=[' A', ' B'])
merged
Out[150]:
                 Date Buy A Sell A           Date_Time Buy B Sell B
0 2009-01-08 04:00:00     0      0 2009-01-08 04:00:00     0     10
1 2009-01-08 04:00:00     0      0 2009-01-08 04:00:00     0     10
2 2009-01-08 04:00:00     0      0 2009-01-08 04:00:00     0     10
3 2009-01-08 05:00:00     0      0 2009-01-08 05:00:00     0     32
4 2009-01-08 05:00:00     0      0 2009-01-08 05:00:00     0     32

显然,在您的案例中将dfdf1替换为frameAframeB

答案 1 :(得分:0)

您可以做的另一件事是将日期设置为索引:

如上面的答案所述,第一步是将它们解析为相同的格式。

frameA = pd.read_csv("fileA.csv", dtype=str, delimiter=";", skiprows = None, parse_dates=['Date'])

frameB = pd.read_csv("fileB.csv", dtype=str, delimiter=";", skiprows = None, parse_dates=[['Date','Time']])

在将数据包含到数组中之后,如上所示,我们可以设置数据的索引来指导合并:

frameA.index = frameA['Date']
frameB.index = frameB['Date']

然后,它们将合并在完全相同的索引上,并且由于它们具有相似的列('Buy','Sell'),我们需要为合并指定后缀:

merge = frameA.join(frameB,lsuffix ='A',rsuffix ='B')

结果看起来就像这样。

                     Buy A   Sell A   Buy B   Sell B
0  01.08.2009 00:15    0       0       0       0
1  01.08.2009 00:30    0       0       0       0

这种方法的优点是,如果你的第二个数据集('买B','卖B')在第一个槽中缺少时间,那么合并仍然有效,你不会将数据错误分配给不合适的时间。假设我们有两个1-10000的任意数字索引,第二个数据帧缺少3个值(索引仅从1-9997开始)。这将导致转移,然后我们不正确地将值分配给错误的索引是引导加入的那个。

在这里,只要指导加入的数据帧比第二个数据帧长,我们就不会丢失任何数据,我们也绝不会将它分配给错误的索引。

例如:

if len(frameA.index) >= len(frameB.index):
    merge = frameA.join(frameB)
else:
    print 'Missing Values, define your own function here'
    quit()

编辑:

确保报告所有数据的另一种方法是,无论它是否出现在两个列中,都将定义一个新数据框,其中包含两个数据框中唯一的日期列表,并使用它来指导合并。

例如,

unique_index = sorted(list(set(frameA.index.tolist() + frameB.index.tolist())))  

通过对两个索引列表求和,将其转换为集合并返回列表来定义唯一索引。设置删除所有冗余值,因此您有一个唯一列表,并且列表已排序,因为集合未被排序。

然后,合并数据帧:

merge = pd.DataFrame(index = unique_index)
merge = merge.join(frameA)
merge = merge.join(frameB, lsuffix = ' A', rsuffix = ' B')

只需确保使用索引ON导出它,或者将索引重新定义为列(导出到csv或excel表自动将索引打开,除非您将其关闭,所以请确保不要设置index =假)。

然后,“买入A”,“卖出A”列中出现的任何缺失数据将出现在“买入B”,“出售B”中,并且“买入B”中缺少数据, “卖A”,“卖A”中出现'卖B'。