我有一个熊猫数据框school_df,看起来像这样:

    school_id  date_posted date_completed
0    A          2014-01-01  2014-01-01
1    A          2014-01-01  2014-01-08
2    A          2014-04-29  2014-05-01
3    B          2014-01-01  2014-01-01
4    B          2014-01-20  2014-02-23


每行代表该学校的一个项目。我想添加两列:对于每个唯一的school_id,该日期之前发布了多少项目的计数,以及该日期之前完成了多少项目的计数。

下面的代码有效,但是我有大约300,000所独特的学校,因此运行起来需要很长时间。有没有更快的方式来获得我想要的东西?谢谢您的帮助!

import pandas as pd
groups = school_df.groupby("school_id")
blank_df = pd.DataFrame()
for g, df in groups:
    df['school_previous_projects'] = df.date_posted.map(lambda x: len(df[df.date_posted < x]))
    df['school_previous_completed'] = df.date_posted.map(lambda x: len(df[df.date_completed < x]))
    blank_df = pd.concat([blank_df, df])

最佳答案

这是一个使用cumcount的版本(我简化了日期,但仍然可以使用):

import pandas as pd
import io


df = pd.DataFrame({'school_id': ['A', 'A', 'A', 'B', 'B'],
                   'date_posted': pd.date_range('2014-01-01', '2014-01-05'),
                   'date_completed': pd.date_range('2014-01-01', '2014-01-05')})

posted = df.set_index('date_posted').groupby('school_id').cumcount()
comp = df.set_index('date_completed').groupby('school_id').cumcount()

df['posted'] = posted.values
df['comp'] = comp.values

print df


结果是:

  date_completed date_posted school_id  posted  comp
0     2014-01-01  2014-01-01         A       0     0
1     2014-01-02  2014-01-02         A       1     1
2     2014-01-03  2014-01-03         A       2     2
3     2014-01-04  2014-01-04         B       0     0
4     2014-01-05  2014-01-05         B       1     1

10-07 15:14