使两个数据帧之间的匹配算法更有效

时间:2018-05-16 17:20:34

标签: python pandas

我有两个数据帧,例如。

更短的时间范围(每小时4小时)

Time                  Data_4h
1/1/01 00:00          1.1
1/1/01 06:00          1.2
1/1/01 12:00          1.3
1/1/01 18:00          1.1
2/1/01 00:00          1.1
2/1/01 06:00          1.2
2/1/01 12:00          1.3
2/1/01 18:00          1.1
3/1/01 00:00          1.1
3/1/01 06:00          1.2
3/1/01 12:00          1.3
3/1/01 18:00          1.1

更长的时间范围(1天)

Time                  Data_1d
1/1/01 00:00          1.1
2/1/01 00:00          1.6
3/1/01 00:00          1.0

我想用更长的时间范围数据标记较短的时间范围数据,但是n-1天,留下NaN,其中n-1天不存在。

例如,

结合4h和1d的最终合并数据

Time                  Data_4h     Data_1d
1/1/01 00:00          1.1         NaN
1/1/01 06:00          1.2         NaN
1/1/01 12:00          1.3         NaN
1/1/01 18:00          1.1         NaN
2/1/01 00:00          1.1         1.1
2/1/01 06:00          1.2         1.1
2/1/01 12:00          1.3         1.1
2/1/01 18:00          1.1         1.1 
3/1/01 00:00          1.1         1.6
3/1/01 06:00          1.2         1.6
3/1/01 12:00          1.3         1.6
3/1/01 18:00          1.1         1.6

所以对于1/1 - 它试图找到31/12但是找不到它所以它被标记为NaN。对于2/1,它搜索了1/1,并将其标记为1.1 - 为1/1的值。对于3/1,它搜索了2/1,并将其标记为1.6 - 2/1的值。

重要的是要注意时间范围数据可能有很大的差距。所以我无法直接访问较大时间范围内的行。

最好的方法是什么?

目前,我正在遍历较小时间范围的所有行,然后使用以下过滤器搜索更大的时间范围日期:

large_tf_data[(large_tf_data.index <= target_timestamp)][0]

在较小的时间帧数据帧中的每一行上计算target_timestamp。

这非常慢!有关如何加快速度的建议吗?

1 个答案:

答案 0 :(得分:1)

首先,照顾日期

dayfirstme = lambda d: pd.to_datetime(d.Time, dayfirst=True)
df = df.assign(Time=dayfirstme)
df2 = df2.assign(Time=dayfirstme)

然后将df2转换为有用的内容

d2 = df2.assign(Time=lambda d: d.Time + pd.Timedelta(1, 'D')).set_index('Time').Data_1d

应用魔法

df.join(df.Time.dt.date.map(d2).rename(d2.name))

                  Time  Data_4h  Data_1d
0  2001-01-01 00:00:00      1.1      NaN
1  2001-01-01 06:00:00      1.2      NaN
2  2001-01-01 12:00:00      1.3      NaN
3  2001-01-01 18:00:00      1.1      NaN
4  2001-01-02 00:00:00      1.1      1.1
5  2001-01-02 06:00:00      1.2      1.1
6  2001-01-02 12:00:00      1.3      1.1
7  2001-01-02 18:00:00      1.1      1.1
8  2001-01-03 00:00:00      1.1      1.6
9  2001-01-03 06:00:00      1.2      1.6
10 2001-01-03 12:00:00      1.3      1.6
11 2001-01-03 18:00:00      1.1      1.6

我确定还有其他方法,但我不想再想这个了。