使用分组依据对象中的"ones"填充缺少的组合



我有以下格式的数据。

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

您可以重新索引groupbymean的结果,并用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

最新更新