【问题标题】:How to create a new boolean column in a dataframe based on multiple conditions from other dataframe in pandas如何根据熊猫中其他数据框的多个条件在数据框中创建新的布尔列
【发布时间】:2018-08-09 00:06:52
【问题描述】:

我有一个数据框

entity  response    date
p   a1  1-Feb-14
p   a2  2-Feb-14
p   a3  3-Feb-14
p   a4  4-Feb-14
p   a5  5-Feb-14
p   a6  6-Feb-14
p   a7  7-Feb-14
p   a8  8-Feb-14
p   a9  9-Feb-14
p   a10 10-Feb-14
p   a11 11-Feb-14
p   a12 12-Feb-14
p   a13 13-Feb-14
p   a14 14-Feb-14
p   a15 15-Feb-14

和另一个数据框:

entity  start_date  end_date
p   2-Feb-14    4-Feb-14
p   6-Feb-14    7-Feb-14
p   9-Feb-14    12-Feb-14
q   1-Feb-14    7-Feb-14

基于第二个数据帧,我必须在第一个数据帧中创建一个 True False 列 对于 P,如果日期位于任何开始和结束日期窗口之间,则它应该为 true,否则为 false。

什么是最快和最短的方法。我尝试遍历整个数据框,但这需要时间并且也会使代码变长

【问题讨论】:

  • 请阅读How to Ask。不要发布数据帧的图片。
  • 我回滚了 OP 的编辑,因为他们最初有实际的数据框(尽管他们没有实际的日期,这会很有帮助)
  • q 是从哪里来的?你为什么把日期写成小写?
  • 我添加了 q 作为示例,因为在其他数据框中可以有许多实体
  • @sacul 我添加了日期

标签: python pandas dataframe


【解决方案1】:

恕我直言,根据您的数据,有时可以先扩展日期范围

df2 = pd.concat([
    pd.DataFrame(pd.date_range(start_date, end_date), columns=['date']).assign(entity=entity)
    for _, (entity, start_date, end_date) in df2.iterrows()
]).drop_duplicates()
df.merge(df2, on=['entity', 'date'], how='left', indicator=True)['_merge'] == 'both'

【讨论】:

    【解决方案2】:

    也许我想多了,但是

    def f(s):
        f2 = lambda d, n: ((d >= df2[df2.entity == n].start_date) & (d <= df2[df2.entity==n].end_date)).any()
        return(s.transform(f2, n=s.name))
    
    df.groupby('entity').date.transform(f)
    
    0     False
    1      True
    2      True
    3      True
    4     False
    5      True
    6      True
    7     False
    8      True
    9      True
    10     True
    11     True
    12    False
    13    False
    14    False
    15    False
    Name: date, dtype
    

    你也可以先做一些预处理来加快进程

    df2['j']  = df2.agg(lambda k: pd.Interval(k.start_date, k.end_date), 1)
    dic = df2.groupby('entity').agg(lambda k: list(k)).to_dict()['j']
    df[['entity', 'date']].transform(lambda x: any(x['date'] in z for z in dic[x['entity']]), 1)
    

    请注意,默认情况下,这使用 pd.Interval 仅在右侧关闭,但应该比链式转换快 20 倍左右。

    【讨论】:

      猜你喜欢
      • 2022-01-15
      • 1970-01-01
      • 1970-01-01
      • 2019-07-25
      • 2019-03-27
      • 1970-01-01
      • 1970-01-01
      • 2019-11-18
      • 1970-01-01
      相关资源
      最近更新 更多