我有两个数据帧,我想根据时间范围将它们连接起来 例如
dataframe A
user timestamp product
A 2015/3/13 1
B 2015/3/15 2
dataframe B
user time behavior
A 2015/3/1 2
A 2015/3/8 3
A 2015/3/13 1
B 2015/3/1 2
我想将2个数据帧连接如下(帧B左连接到帧A) 列" timestamp1"在列#34;时间戳"之前7天 例如,当时间戳为3/13时,则3 / 6-13在该范围内 否则不要结束
user timestamp product time1 behavior
A 2015/3/13 1 2015/3/8 3
A 2015/3/13 1 2015/3/13 1
B 2015/3/15 2 NaN NaN
sql代码看起来像
select * from
B left join A
on user
where B.time >= A.timestamp - 7 & B.time <= A.timestamp
##WHERE B.time BETWEEN DATE_SUB(B.time, INTERVAL 7 DAY) AND A.timestamp ;
我们如何才能在python上实现这个目标?
只能想到以下内容并且不知道如何使用时间..
new = pd.merge(A, B, on='user', how='left')
谢谢,抱歉..
答案 0 :(得分:2)
解决此问题所需的几个步骤 -
from datetime import timedelta
首先,将时间戳转换为pandas datetime。 (df1表示数据帧A,df2表示数据帧B)
df1[['time']]=df1[['timestamp']].apply(pd.to_datetime)
df2[['time']]=df2[['time']].apply(pd.to_datetime)
合并如下:(根据您的最终数据集,我认为您的左连接更多是正确的连接)
df3 = pd.merge(df1,df2,how='left')
获取最终的df:
df4 = df3[(df3.time>=df3.timestamp-timedelta(days=7)) & (df3.time<=df3.timestamp)]
包含nan的行缺失,这是因为在pandas中完成条件连接的方式。
Condtional join还不是熊猫的特色。一种过去的方法是通过过滤加入过滤。
答案 1 :(得分:0)
这是一个依赖于两个合并的解决方案 - 首先,缩小dataframe B
(df2
),然后生成所需的输出:
我们可以在示例数据框中阅读read_clipboard()
:
import pandas as pd
# copy dataframe A data, then:
df1 = pd.read_clipboard(parse_dates=['timestamp'])
# copy dataframe B data, then:
df2 = pd.read_clipboard(parse_dates=['time'])
合并并过滤:
# left merge df2, df1
tmp = df2.merge(df1, on='user', how='left')
# then drop rows which disqualify based on timestamp
mask = tmp.time < (tmp.timestamp - pd.Timedelta(days=7))
tmp.loc[mask, ['time', 'behavior']] = None
tmp = tmp.dropna(subset=['time']).drop(['timestamp','product'], axis=1)
# now perform final merge
merged = df1.merge(tmp, on='user', how='left')
输出:
user timestamp product time behavior
0 A 2015-03-13 1 2015-03-08 3.0
1 A 2015-03-13 1 2015-03-13 1.0
2 B 2015-03-15 2 NaT NaN