查找唯一值的累积数量

时间:2016-03-02 22:07:42

标签: pandas

我是一个Pandas DF,其他列中有一个日期列和一个ID列。我需要按日期对此数据进行分组/排序,并且每个日期计算自第一行(时间轴的开始)以来看到的唯一ID的数量。有没有办法用pandas / numpy做这个而不用写出循环?

3 个答案:

答案 0 :(得分:2)

了解pandas.unique:

import pandas as pd
for date in pd.unique(df['Date']):
    unique_ids = pd.unique(df[df['Date']==date]['id'])
    print len(unique_ids)

编辑第二次尝试

newdf = df[['Date', 'id']].drop_duplicates()
newdf.groupby('Date').count()

答案 1 :(得分:2)

至少现在很清楚OP想要什么......

print(df.groupby('date').id.nunique().cumsum())

测试数据集:

date;id
2012-03-31;111
2012-03-31;2
2012-03-31;1
2012-03-31;4
2012-04-01;15
2012-04-01;6
2012-04-01;7
2012-04-01;118
2012-04-01;9
2012-05-01;10
2012-05-01;11

两种不同方法的比较:

import pandas as pd

df = pd.read_csv('data.csv', sep=';').sort('date')


print(df[['date','id']].drop_duplicates(['id']).groupby('date').count().cumsum())
print(df.groupby('date').id.nunique().cumsum())

输出:

            id
date
2012-03-31   4
2012-04-01   9
2012-05-01  11
date
2012-03-31     4
2012-04-01     9
2012-05-01    11
Name: id, dtype: int64

PS所以它确实返回了正确的结果。至少对于那个数据集。这就是为什么提供测试数据集和预期输出很重要的原因!

PPS另一个有趣的观察结果:

from timeit import Timer
import pandas as pd

df = pd.read_csv('data.csv', sep=';', parse_dates=['date']).sort_values(['date'])

def drop_dups():
    df[['date','id']].drop_duplicates(['id']).groupby('date').count().cumsum()

def nunique():
    df.groupby('date').id.nunique().cumsum()


print('drop_dups():\t{:.6f}'.format(Timer(drop_dups).timeit(1000)))
print('nunique():\t{:.6f}'.format(Timer(nunique).timeit(1000)))

输出:

drop_dups():    6.722572
nunique():      1.512233

答案 2 :(得分:1)

由于其余答案都无法解决我的问题,因此我对以下代码段进行了编码。

因此,此代码段将包含从每次迭代开始到最近一周的唯一ID数量。上述答案给了我这些唯一ID的累积和,从而导致不匹配。

ex:用于以下输入:

周号
2020-12-04 101
2020-12-04 102
2020-12-11 101
2020-12-11 103

此处提到的其他代码的输出:

2020-12-04:2
2020-12-11:4

我想要的输出是:

2020-12-04:2
2020-12-11:3

此代码段是:

for date in pd.unique(df['week']):
       print(date,"\t",df[df['week']<=date].id.nunique())

我不确定OP是否希望获得相同的输出,但这只是为了防止有人以我提到的方式需要输出