基于groupby值比较创建新变量(&V)

2024-04-23 23:39:20 发布

您现在位置:Python中文网/ 问答频道 /正文

很抱歉这篇文章的名字不太正确。这项任务由几个部分组成,我不知道如何准确地表述。我有一个这样的数据帧

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表示特定员工当天未关闭的项目数。第0行中的值为3,因为项目开始时间为2018-01-01,并且该员工在该日期有三个当前项目。你知道吗

我是怎么解决这个问题的 首先,我需要得到每个员工的项目结束/开始日期列表

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

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


Tags: to项目iniddfnewfordatetime
1条回答
网友
1楼 · 发布于 2024-04-23 23:39:20

您也可以使用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)

相关问题 更多 >