【问题标题】:Create new variable based on groupby & value comparison基于 groupby 和值比较创建新变量
【发布时间】:2019-05-21 01:06:56
【问题描述】:

对于这篇文章的名称不完全正确,我深表歉意。该任务由几个部分组成,我不知道如何准确制定。我有一个这样的数据框

df = pd.DataFrame({'id': (1,1,1,2,2), 'begin': ('01.01.2018','01.02.2018', '01.03.2018', '01.01.2018', '01.02.2018'),
    'end': ('01.02.2018','01.03.2018', '01.04.2018', '01.02.2018', '01.03.2018')})
df['begin']= pd.to_datetime(df['begin'])
df['end']= pd.to_datetime(df['end'])
df
      begin        end     id
0   2018-01-01  2018-01-02  1
1   2018-01-02  2018-01-03  1
2   2018-01-03  2018-01-04  1
3   2018-01-01  2018-01-02  2
4   2018-01-02  2018-01-03  2

其中begin 是项目开始时间,end 是项目结束时间,id 是员工。我想创建一个新变量

      begin       end      id  new
0   2018-01-01  2018-01-02  1   3
1   2018-01-02  2018-01-03  1   2
2   2018-01-03  2018-01-04  1   1
3   2018-01-01  2018-01-02  2   2
4   2018-01-02  2018-01-03  2   1

new 表示特定员工在该日期未完成的项目数。在项目开始时间为 2018-01-01 时,第 0 行中的值为 3,并且该员工在该日期有三个当前项目。

我是如何解决这个问题的 首先,我需要获取每个员工的项目结束/开始日期列表

gr_end = df.groupby(['id'])['end'].apply(list)
gr_begin = df.groupby(['id'])['begin'].apply(list)

现在是最困难的。我必须将每个员工的项目开始日期与每个项目的结束日期进行比较。我必须计算开始日期小于结束日期的所有情况

l = []
for i in gr_begin.index:
    for x in gr_begin[i]:
        cv = [j == 1 for j in gr_end[i] if j > x].count(False)
        l.append(cv)
df['new'] = l

首先,我请您检查我是否正确编写了循环。最重要的是,我相信这是可以做到的,但更短更方便。如果有任何想法,我将不胜感激。

【问题讨论】:

    标签: python pandas for-loop pandas-groupby


    【解决方案1】:

    您也可以使用merge 来做到这一点

    merged = df.merge(df.drop(columns='end'), on='id', suffixes=('', '_y'))
    live_projects = merged[merged.begin<=merged.begin_y]
    result = live_projects.groupby(['id','begin','end']).count().reset_index()
    result.rename(columns={'begin_y':'new'}, inplace=True)
    

    【讨论】:

      猜你喜欢
      • 2018-06-05
      • 1970-01-01
      • 1970-01-01
      • 2021-12-09
      • 2020-08-24
      • 1970-01-01
      • 2021-09-30
      • 2023-03-14
      • 1970-01-01
      相关资源
      最近更新 更多