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

0 投票
2 回答
1370 浏览
提问于 2025-04-29 11:30

我有两个csv文件,它们的日期格式和长度都不一样。

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

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

文件A有102216行和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行和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

你还可以把日期设置为索引:

正如上面的回答所说,第一步是把它们解析成相同的格式。

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']

这样,它们就会在完全相同的索引上合并,而且因为它们有相似的列('买入','卖出'),我们需要为合并指定后缀:

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的任意数字索引,而第二个数据框只包含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')

只要确保导出时索引是开启的,或者把索引重新定义为一列(导出到csv或excel表格时,索引默认是开启的,除非你关闭它,所以一定要确保没有设置index = False)。

这样,任何在'买入 A','卖出 A'列中缺失但在'买入 B','卖出 B'中存在的数据会显示为'nan',同样,'买入 B','卖出 B'中缺失但在'买入 A','卖出 A'中存在的数据也会显示为'nan'。

1

好的,首先要确保第一个数据框(df)的时间数据类型是日期时间:

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']])

接下来,我会像这样重置第一个数据框的分钟值:

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

现在我们可以把这两个数据框合并在一起:

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

撰写回答