Python 熊猫在正确的时间增加价值
我有两个按日期索引的数据帧,一个数据帧上的行每小时更改一次,另一个数据帧上的行每更改一次(有时每5分钟更改一次,有时有不同的步骤) 我希望h和h+1之间的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
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中。应该在下一次大熊猫发布时修复。