基于条件的Python Pandas数据框分组大小

6

我有一个名为'df'的数据框,长这样:

id  date1   date2
1   11/1/2016   11/1/2016
1   11/1/2016   11/2/2016
1   11/1/2016   11/1/2016
1   11/1/2016   11/2/2016
1   11/2/2016   11/2/2016
2   11/1/2016   11/1/2016
2   11/1/2016   11/2/2016
2   11/1/2016   11/1/2016
2   11/2/2016   11/2/2016
2   11/2/2016   11/2/2016

我希望做的是按照id分组,然后获取每个id在date1等于date2时的大小。结果应该如下所示:

id  samedate    count
1   11/1/2016    2 
1   11/2/2016    1 
2   11/1/2016    2 
2   11/2/2016    2 

我已经尝试过这个:
gb=df.groupby(id').apply(lambda x: x[x.date1== x.date2]['date1'].size())

并获得此错误:

TypeError: 'int' object is not callable

您可以标记每个日期1和日期2相等的实例,然后按照每个samedate为每个id计算这些标记的数量,但我相信这里有一个分组选项。
2个回答

5

您可以先使用布尔索引,然后再聚合size

df.date1 = pd.to_datetime(df.date1)
df.date2 = pd.to_datetime(df.date2)

df = df[df.date1 == df.date2]
gb=df.groupby(['id', 'date1']).size().reset_index(name='count')
print (gb)
   id      date1  count
0   1 2016-11-01      2
1   1 2016-11-02      1
2   2 2016-11-01      2
3   2 2016-11-02      2

时间:

In [79]: %timeit (df[df.date1 == df.date2].groupby(['id', 'date1']).size().reset_index(name='count'))
100 loops, best of 3: 3.84 ms per loop

In [80]: %timeit (df.groupby(['id', 'date1']).apply(lambda x: (x['date1'] == x['date2']).sum()).reset_index())
100 loops, best of 3: 7.57 ms per loop

计时代码:

#len df = 10k
df = pd.concat([df]*1000).reset_index(drop=True)
#print (df)

df.date1 = pd.to_datetime(df.date1)
df.date2 = pd.to_datetime(df.date2)

感谢您提供时间。这是更好的做法。 - Zero
谢谢您的回答,我的第一个想法与您的答案非常相似。 - jezrael

3

您需要按两个列进行分组,然后应用检查date1是否等于date2

In [105]: df.groupby(['id', 'date1']).apply(lambda x: (x['date1'] == x['date2']).sum())
Out[105]:
id  date1
1   11/1/2016    2
    11/2/2016    1
2   11/1/2016    2
    11/2/2016    2
dtype: int64

如果您对整个集合应用lambda函数,并且在lambda函数内执行布尔比较,那么您的速度将比jezrael慢。 - Zeugma

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接