我有以下格式的数据。
date group ret
1986-01-31 1 1.3
1986-01-31 1 0.9
1986-01-31 2 1.4
1986-01-31 2 1.6
1986-01-31 2 1.5
1986-01-31 3 1.1
1986-02-28 2 1.3
1986-02-28 2 1.1
我想获得每个日期和组的平均回报,这是我通过以下操作获得的:
output = df.groupby(['date', 'group'])['ret'].mean() + 1
output = output.reset_index()
它给出以下输出:
date group ret
1986-01-31 1 1.1
1986-01-31 2 1.5
1986-01-31 3 1.1
1986-02-28 2 1.2
然而,由于没有";ret";在1986-02-28年的日期为1类和3类,在该日期的输出中没有第1类和第3类的行。我想要的是,对于原始数据帧中没有返回的日期和类的任何组合,该组合获得并输出";1〃;在输出中。因此,所需的输出是:
date group ret
1986-01-31 1 1.1
1986-01-31 2 1.5
1986-01-31 3 1.1
1986-02-28 1 1
1986-02-28 2 1.2
1986-02-28 3 1
什么是解决这个问题的好办法?提前感谢!
我们可以先进行pivot_table
,然后进行stack
out = df.pivot_table(index='date',columns='group',values='ret',aggfunc = 'mean').fillna(1).stack().reset_index(name='value')
date group value
0 1986-01-31 1 1.1
1 1986-01-31 2 1.5
2 1986-01-31 3 1.1
3 1986-02-28 1 1.0
4 1986-02-28 2 1.2
5 1986-02-28 3 1.0
您可以重新索引groupby
和mean
的结果,并用1填充空值:
output = df.groupby(['date', 'group'])['ret'].mean().reindex(
pd.MultiIndex.from_product(
(pd.date_range(df.date.min(), df.date.max(), freq='M'),
sorted(df.group.unique())),
names=['date', 'group'],
)
).fillna(1).reset_index()
以下是您问题中DataFrame的结果:
date group ret
0 1986-01-31 1 1.1
1 1986-01-31 2 1.5
2 1986-01-31 3 1.1
3 1986-02-28 1 1.0
4 1986-02-28 2 1.2
5 1986-02-28 3 1.0
您可以使用pyjanitor中的完整函数来公开显式缺失的值,并使用1
:填充
# pip install pyjanitor
import janitor
(df.groupby(['date', 'group'], as_index = False)
.ret
.mean()
.complete(['date', 'group'])
.fillna(1)
)
date group ret
0 1986-01-31 1 1.1
1 1986-01-31 2 1.5
2 1986-01-31 3 1.1
3 1986-02-28 1 1.0
4 1986-02-28 2 1.2
5 1986-02-28 3 1.0
或者,您可以将group
列转换为分类数据类型,所有类别都将在分组期间通过以下方式进行维护:
from pandas.api.types import CategoricalDtype
(df
.astype({"group": CategoricalDtype(categories=df.group.unique())})
.groupby(['date', 'group'], as_index = False)
.ret
.mean()
.fillna(1)
)
date group ret
0 1986-01-31 1 1.1
1 1986-01-31 2 1.5
2 1986-01-31 3 1.1
3 1986-02-28 1 1.0
4 1986-02-28 2 1.2
5 1986-02-28 3 1.0