Python 将缺少的组合填上“;“一”;在groupby对象中

Python 将缺少的组合填上“;“一”;在groupby对象中,python,pandas,pandas-groupby,Python,Pandas,Pandas Groupby,我有以下格式的数据 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 我希望获得每个日期和组的平均回报,我通过以下操

我有以下格式的数据

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
然而,由于在1986年2月28日没有给出1类和3类的“ret”,因此在该日期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\u 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
的结果索引,并用以下值填充空值:

output=df.groupby(['date','group'])['ret'].mean().reindex(
pd.MultiIndex.from_乘积(
(pd.date_范围(df.date.min(),df.date.max(),freq='M'),
已排序(df.group.unique()),
名称=[“日期”,“组”],
)
).fillna(1).reset_index()
下面是您问题中数据帧的结果:

日期组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
您可以使用函数from公开显式缺少的值,并使用
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
或者,您可以将
列转换为a,所有类别将在groupby期间维护:

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