在Pandas中,如何获得唯一值的数量,直到时间T?

时间:2016-04-09 12:29:02

标签: python pandas

考虑以下数据集

df=pd.DataFrame({'A':pd.date_range('2012-02-02','2012-02-07'),
                 'ID':['A','B','A','D','A',np.NaN]})      

df
Out[122]: 
           A    ID
0 2012-02-02    A
1 2012-02-03    B
2 2012-02-04    A
3 2012-02-05    D
4 2012-02-06    A
5 2012-02-07  NaN

我想获取ID的唯一值的数量,直到时间t 。这意味着输出应该看起来像

Out[122]: 
           A    uniqueID
0 2012-02-02    1
1 2012-02-03    2
2 2012-02-04    2
3 2012-02-05    3
4 2012-02-06    3
5 2012-02-07    3

事实上,在2月3日,我们知道ID有两个独特的价值(' A'和' B')。在2月4日我们看到了A'但我们知道已经这样了,所以我们不会增加唯一ID值的数量。

我没有看到使用groupby.agg('nunique')这样做的简单方法。任何想法都是受欢迎的。

谢谢!

编辑:

试图了解edchum解决方案......

df.apply(lambda x: df['ID'].iloc[:x.name+1],axis=1)
Out[134]: 
   0    1    2    3    4   5
0  A  NaN  NaN  NaN  NaN NaN
1  A    B  NaN  NaN  NaN NaN
2  A    B    A  NaN  NaN NaN
3  A    B    A    D  NaN NaN
4  A    B    A    D    A NaN
5  A    B    A    D    A NaN

1 个答案:

答案 0 :(得分:1)

apply使用loc对df进行切片并使用.name对行索引值进行切片并计算ID列的nunique次数的lambda:

In [5]:
df['Unique_ID'] = df.apply(lambda x: df['ID'].loc[:x.name].nunique(),axis=1)
df
Out[5]:
           A   ID  Unique_ID
0 2012-02-02    A          1
1 2012-02-03    B          2
2 2012-02-04    A          2
3 2012-02-05    D          3
4 2012-02-06    A          3
5 2012-02-07  NaN          3

修改

这是一个细分,如果我们修改df所以索引不是int生成的:

In [19]:
df=pd.DataFrame({'A':pd.date_range('2012-02-02','2012-02-07'),
                 'ID':['A','B','A','D','A',np.NaN]}, index=list('abcdef'))  
df

Out[19]:
           A   ID
a 2012-02-02    A
b 2012-02-03    B
c 2012-02-04    A
d 2012-02-05    D
e 2012-02-06    A
f 2012-02-07  NaN

所以我们看到name在这种情况下实际上是行系列索引值:

In [20]:
df.apply(lambda x: print(x.name),axis=1).tolist()

a
b
c
d
e
f

所以我们可以使用它来使用loc对df进行切片,其范围最大并包括此索引值:

In [22]:
df.apply(lambda x: print(df['ID'].loc[:x.name]),axis=1)

a    A
Name: ID, dtype: object
a    A
b    B
Name: ID, dtype: object
a    A
b    B
c    A
Name: ID, dtype: object
a    A
b    B
c    A
d    D
Name: ID, dtype: object
a    A
b    B
c    A
d    D
e    A
Name: ID, dtype: object
a      A
b      B
c      A
d      D
e      A
f    NaN
Name: ID, dtype: object

因此,您可以从上面看到我们正在递增每行的切片范围,然后我们可以在此处调用nunique以返回此范围内看到的唯一值的数量:

In [24]:
df.apply(lambda x: print(df['ID'].loc[:x.name].nunique()),axis=1)

1
2
2
3
3
3