【问题标题】:how to concat 2 pandas dataframe based on time ranges如何根据时间范围连接 2 个 pandas 数据帧
【发布时间】:2017-05-02 19:39:42
【问题描述】:

我有两个数据框,我想根据时间范围连接它们 例如

数据框 A

user   timestamp    product
 A      2015/3/13      1
 B      2015/3/15      2

数据框 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”列在“timestamp”列之前 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')

谢谢,对不起..

【问题讨论】:

  • 您的时间/时间戳字段是否已格式化为 pandas 日期时间?
  • 您是否希望加入一年中同一周的行,或者在“时间戳”列中的日期始终作为参考,因为它们定义了周的结束点?

标签: python pandas time


【解决方案1】:

解决这个问题所需的几个步骤-

from datetime import timedelta 

首先,将您的时间戳转换为 pandas 日期时间。 (df1 指 Dataframe A,df2 指 Dataframe 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 中进行条件连接的方式。

条件连接还不是 pandas 的功能。一种解决方法是通过过滤发布加入。

【讨论】:

  • 如果它解决了您的问题,请不要忘记接受答案:)
【解决方案2】:

这是一个依赖于两个合并的解决方案 - 首先,缩小 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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2022-09-23
    • 1970-01-01
    • 2021-10-25
    • 2018-09-13
    • 2020-09-02
    • 1970-01-01
    • 2019-01-13
    • 1970-01-01
    相关资源
    最近更新 更多