Python 熊猫在正确的时间增加价值

Python 熊猫在正确的时间增加价值,python,pandas,dataframe,merge,Python,Pandas,Dataframe,Merge,我有两个按日期索引的数据帧,一个数据帧上的行每小时更改一次,另一个数据帧上的行每更改一次(有时每5分钟更改一次,有时有不同的步骤) 我希望h和h+1之间的df1值具有相应的df2值 通缉结果: >>> print df1['value'] date 2015-10-06 09:05:00 0.612303 2015-10-06 09:08:00 0.612303 2015-10-06 09:28:00 0.612303 2015-10-06 10:15:00

我有两个按日期索引的数据帧,一个数据帧上的行每小时更改一次,另一个数据帧上的行每更改一次(有时每5分钟更改一次,有时有不同的步骤)

我希望h和h+1之间的
df1
值具有相应的
df2

通缉结果:

>>> print df1['value']
date
2015-10-06 09:05:00    0.612303
2015-10-06 09:08:00    0.612303
2015-10-06 09:28:00    0.612303
2015-10-06 10:15:00    0.482605
2015-10-06 11:00:00    0.604132

如何实现这一点?

在df1中,根据索引创建一个新列“hourly” 然后在这个新创建的列上简单地连接df1和df2,以添加来自df2的值

将尽快发布代码:)

编辑:正如承诺的那样,下面是代码

import pandas as pd
from datetime import datetime

df1 = pd.read_csv("df1.csv",index_col="date", parse_dates=True)
df2 = pd.read_csv("df2.csv",index_col="date", parse_dates=True)


def fromTimeStampToHour(date):
    datetimeObj = date.to_datetime()
    hourlyObj = datetime(year=datetimeObj.year,month= datetimeObj.month, day = datetimeObj.day, hour=datetimeObj.hour)
    return hourlyObj

df1["Hours"] = df1.index.map(lambda x: fromTimeStampToHour(x))

print pd.merge(left=df1,  right=df2, left_on="Hours", right_index=True, suffixes=("_df1", "_df2"))

有关0.19.0或更高版本的信息,请参阅


对于Pandas版本<0.19.0:您可以使用
concat
组合两个数据帧,使用
ffill
使用所需的值向前填充NaN值,然后使用这些值更新
df1

import pandas as pd
df2 = pd.DataFrame({'value':[0.612303,0.482605,0.604132]}, index=pd.DatetimeIndex(['2015-10-06 09:00:00', '2015-10-06 10:00:00', '2015-10-06 11:00:00']))
df1 = pd.DataFrame({'value':[0.412303, 0.112303, 0.012303, 0.000005, 0.133132]}, index=pd.DatetimeIndex(['2015-10-06 09:05:00', '2015-10-06 09:08:00', '2015-10-06 09:28:00', '2015-10-06 10:15:00', '2015-10-06 11:00:00']))

df1.update(pd.concat([df1, df2], axis=1).ffill().iloc[:, 1])
print(df1)
屈服

                        value
2015-10-06 09:05:00  0.612303
2015-10-06 09:08:00  0.612303
2015-10-06 09:28:00  0.612303
2015-10-06 10:15:00  0.482605
2015-10-06 11:00:00  0.604132
                        value
2015-10-06 09:05:00  0.612303
2015-10-06 09:08:00  0.612303
2015-10-06 09:28:00  0.612303
2015-10-06 10:15:00  0.482605
2015-10-06 11:00:00  0.604132

或者,您可以使用
searchsorted
查找索引值,这些索引值指示
df1.index
适合
df2.index

import pandas as pd
df2 = pd.DataFrame({'value':[0.612303,0.482605,0.604132]}, index=pd.DatetimeIndex(['2015-10-06 09:00:00', '2015-10-06 10:00:00', '2015-10-06 11:00:00']))
df1 = pd.DataFrame({'value':[0.412303, 0.112303, 0.012303, 0.000005, 0.133132]}, index=pd.DatetimeIndex(['2015-10-06 09:05:00', '2015-10-06 09:08:00', '2015-10-06 09:28:00', '2015-10-06 10:15:00', '2015-10-06 11:00:00']))

df1['value'] = df2.iloc[df2.index.searchsorted(df1.index, side='right')-1].values
print(df1)
屈服

                        value
2015-10-06 09:05:00  0.612303
2015-10-06 09:08:00  0.612303
2015-10-06 09:28:00  0.612303
2015-10-06 10:15:00  0.482605
2015-10-06 11:00:00  0.604132
                        value
2015-10-06 09:05:00  0.612303
2015-10-06 09:08:00  0.612303
2015-10-06 09:28:00  0.612303
2015-10-06 10:15:00  0.482605
2015-10-06 11:00:00  0.604132
请注意,
searchsorted
假定
df2.index
已按排序顺序排序。如果不是,则首先使用
df2=df2.sort_index()

相反,
pd.concat
返回其DatatimeIndex处于排序状态的数据帧 顺序,即使
df1.index
和/或
df2.index
未按排序顺序排列。因此,对于第一种方法,不需要调用
sort\u index


在这两种方法中,
searchsorted
更快。例如,使用此设置:

import numpy as np
import pandas as pd
N = 1000
df1 = pd.DataFrame(np.random.random(N), index=pd.date_range('2000-1-1', periods=N, freq='14T'))
df2 = pd.DataFrame(np.random.random(int(N/60*14)), index=pd.date_range('2000-1-1', periods=int(N/60*14), freq='1H'))
df3, df4 = df1.copy(), df1.copy()

df3.update(pd.concat([df3, df2], axis=1).ffill().iloc[:, 1])
df4[0] = df2.iloc[df2.index.searchsorted(df4.index, side='right')-1].values
assert df3.equals(df4)
searchsorted
快约2.8倍:

In [88]: %timeit df3.update(pd.concat([df3, df2], axis=1).ffill().iloc[:, 1])
100 loops, best of 3: 2.13 ms per loop

In [89]: %timeit df4[0] = df2.iloc[df2.index.searchsorted(df4.index, side='right')-1].values
1000 loops, best of 3: 744 µs per loop

In [90]: len(df1), len(df2)
Out[90]: (1000, 233)
您可以使用为示例生成一列正确的DatetimeIndex值:

pd.merge_asof(df1.reset_index(), # see note about reset_index below
              df2.reset_index(),
              on='date', 
              tolerance=pd.Timedelta('1H'))
“容差”参数允许您指定合并在特定时间后的有效时间。例如,如果我们指定
tolerance=pd.Timedelta('10m')
(10分钟),则并非所有的值都可以合并,而某些位置被标记为
NaN



请注意,在合并之前,我必须重置两帧的索引。我想使用
left\u index=True
right\u index=True
进行合并,但pandas在传递公差参数时拒绝允许这样做(这可能是一个错误-如果更改,使用
merge\u asof
在这里应该更整洁)。

就是为了这个目的而存在的。@ajcr解决了我的问题。谢谢,你想写一个答案让我接受吗?我已经用下面的
merge\u asof
添加了一个答案-如果你想了解更多细节,请告诉我。FWIW我已经在…上打开了一个问题,并且一个已合并到master中。应该在下一次大熊猫发布时修复。