考虑以下数据集
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
答案 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