我有这个Pandas 数据框:


df = pd.DataFrame(
         {"CALDT": ["1980-01-31", "1980-02-28", "1980-03-31",
                    "1980-01-31", "1980-02-28", "1980-03-31",
                    "1980-01-31"],
          "ID": [1, 1, 1, 
                 2, 2, 2,
                 3],
          "Return": [0.02, 0.05, 0.10,
                     0.05, -0.02, 0.03,
                     -0.03]
          })

df['Year'] = pd.to_datetime(df['CALDT']).dt.year

我的目标是:如果ID还活着&>=2个月,对于每个ID和年份(分组),基于Return,计算平均值和中位数乘以12,并将该值分配回该行.

预期输出应如下所示:

df_new = pd.DataFrame(
    {"CALDT": ["1980-01-31", "1980-02-28", "1980-03-31",
               "1980-01-31", "1980-02-28", "1980-03-31",
               "1980-01-31"],
     "Year": [1980, 1980, 1980,
              1980, 1980, 1980,
              1980],
     "ID": [1, 1, 1, 
            2, 2, 2,
            3],
     "Return": [0.02, 0.05, 0.10,
                0.05, -0.02, 0.03,
                0.03],
     "Mean_Return": [0.68, 0.68, 0.68,
                     0.24, 0.24, 0.24,
                     np.nan],
     "Median_Return": [0.60, 0.60, 0.60,
                       0.36, 0.36, 0.36,
                       np.nan]
     })


在R中,使用tidyverse中的group_by就很容易做到这一点:

df = df %>% 
  mutate(Year = year(CALDT)) %>% 
  group_by(CRSP_FUNDNO, Year) %>% 
  mutate(months_alive = length(unique(CALDT))) %>% 
  mutate(mean = case_when(months_alive >= 2 ~ mean(Return)*3,
                          .default = NA)) %>% 
  mutate(median = case_when(months_alive >= 2 ~ mean(Return)*12,
                            .default = NA))

如有任何帮助,我们将不胜感激!

推荐答案

g = df.groupby(["ID", df.CALDT.dt.year])
return_stats = pd.DataFrame({
                     "Mean_Return": g["Return"].transform("mean").mul(12),
                     "Median_Return": g["Return"].transform("median").mul(12)
                  }).where(g["CALDT"].transform("nunique").ge(2))

df.join(return_stats)
  • 按"ID"和年份分组(我们不必创建新的列作为分组依据)
  • transform(而不是例如agg)计算所需的统计数据的"返回",即平均值和中位数,以便它"广播",即重复计算的值与组的大小相同,而不是单个标量聚合
  • 仅保留统计数据where每组unique个"CALDT"条目的n个数等于ge等于2
  • 把这个和原来的框架连接起来

得到

       CALDT  ID  Return  Mean_Return  Median_Return
0 1980-01-31   1    0.02         0.68           0.60
1 1980-02-28   1    0.05         0.68           0.60
2 1980-03-31   1    0.10         0.68           0.60
3 1980-01-31   2    0.05         0.24           0.36
4 1980-02-28   2   -0.02         0.24           0.36
5 1980-03-31   2    0.03         0.24           0.36
6 1980-01-31   3   -0.03          NaN            NaN

Python相关问答推荐

如何分割我的收件箱,以便连续的数字各自位于自己的收件箱中?

在Python中,什么表达相当于0x1.0p-53?

Pandas 在时间序列中设定频率

根据网格和相机参数渲染深度

根据不同列的值在收件箱中移动数据

试图找到Python方法来部分填充numpy数组

ModuleNotFound错误:没有名为flags.State的模块; flags不是包

如何列举Pandigital Prime Set

如何在python xsModel库中定义一个可选[December]字段,以产生受约束的SON模式

无法在Docker内部运行Python的Matlab SDK模块,但本地没有问题

多指标不同顺序串联大Pandas 模型

什么是最好的方法来切割一个相框到一个面具的第一个实例?

如何在FastAPI中为我上传的json文件提供索引ID?

如何更改groupby作用域以找到满足掩码条件的第一个值?

在Python中计算连续天数

Geopandas未返回正确的缓冲区(单位:米)

在pandas/python中计数嵌套类别

Python—转换日期:价目表到新行

导入错误:无法导入名称';操作';

Numpyro AR(1)均值切换模型抽样不一致性