将groupby的第一个值设置为Nan

时间:2019-07-07 16:32:34

标签: python pandas pandas-groupby

我有一个不同类别的时间序列

cat date        price
A   2000-01-01  100
A   2000-02-01  101
...
A   2010-12-01  140
B   2000-01-01  10
B   2000-02-01  10.4
...
B   2010-12-01  11.1
...
Z   2010-12-01  13.1    

我需要计算所有资产的收益,这是非常快速的

df['ret'] = df['price'] / df['price'].shift(1) - 1

但是,这还会根据对前一个公司的最后观察得出每个公司的第一个元素(除A之外)的不正确回报。因此,我想让每个类别的第一个观察结果都没有。

使用这些信息很容易获得

df.groupby('cat')['ret'].first()

但是我对如何设置它们有些迷惑。

df.groupby('cat')['ret'].first() = np.NaN

df.loc[df.groupby('cat')['ret'].first(), 'ret']=np.NaN

没有领导任何地方。

2 个答案:

答案 0 :(得分:2)

将每个组的第一个值设置为缺少的值,请使用Series.duplicated

df.loc[~df['cat'].duplicated(), 'ret']=np.NaN

但是似乎需要DataFrame.sort_valuesGroupBy.pct_change

df = df.sort_values(['cat','date'])
df['ret1'] = df.groupby('cat')['price'].pct_change()

您的解决方案应使用DataFrameGroupBy.shift进行更改:

df['ret2'] = df['price'] / df.groupby('cat')['price'].shift(1) - 1
print (df)
  cat        date  price      ret1      ret2
0   A  2000-01-01  100.0       NaN       NaN
1   A  2000-02-01  101.0  0.010000  0.010000
2   A  2010-12-01  140.0  0.386139  0.386139
3   B  2000-01-01   10.0       NaN       NaN
4   B  2000-02-01   10.4  0.040000  0.040000
5   B  2010-12-01   11.1  0.067308  0.067308
6   Z  2010-12-01   13.1       NaN       NaN

答案 1 :(得分:2)

尝试

df.sort_values('date').groupby('cat')['price'].pct_change()