如何在 pandas 中按多个列值进行分组并应用 ifelse 来插补/计算值

我有一个如下所示的数据框 df


Node COMMODITY_CODE DAY Capacity_Case  Capacity_Delivery case_ratio deliveries_ratio  window_count

7014.0      SCFZ    1   26610.0         12.0                0.357854    0.354839.            3

7014.0      SCFZ    2   25551.0         11.0                0.457945    0.423077             3

7014.0      SCFZ    3   30669.0         13.0                0.283379    0.258621             3

7030.0      SCDD    1   34244.0         16.0                0.316505    0.300000             4

7030.0      SCDD    2   25954.0         13.0                0.236513    0.232558             4

我想按 Node、DAY、COMMODITY_CODE 进行分组,并应用 ifelse 函数来估算空记录的值。这里我的条件如下:

  1. 对于组(节点、DAY、COMMODITY_CODE)

    1. 如果 Delivery_ratio 为空,那么我想用组的mean(delivery_ratio) 替换并将其分配给delivery_ratio_filled

    2. 如果 case_ratio 为空,那么我想用组的mean(case_ratio) 替换并将其分配给case_ratio_filled

  2. 如果对于组(Node, DAY, COMMODITY_CODE),

    1. Delivery_ratio_filled 为 null,则为其分配 1/window_count 值

    2. case_ratio_filled 为 null,则为其分配 1/window_count

我已经使用 dplyr 包在 R 中轻松完成了此任务,我基本上希望使用 pandas 在 Python 中实现相同的功能。

df %>%

group_by(Node, DAY_OF_WK, COMMODITY_CODE) %>%

  mutate(delivery_ratio_filled = ifelse(!is.na(delivery_ratio),

                               delivery_ratio, 

                               mean(delivery_ratio)),

         case_ratio_filled = ifelse(!is.na(case_ratio),

                               case_ratio, 

                               mean(case_ratio))) %>%

  mutate(delivery_ratio_filled = ifelse(!is.na(delivery_ratio_filled),

                               delivery_ratio_filled,

                               1.0 / window_count),

         case_ratio_filled = ifelse(!is.na(case_ratio_filled),

                               case_ratio_filled,

                               1.0 / window_count))


UYOU
浏览 128回答 2
2回答

当年话下

不幸的是,示例输入数据不包含na将被计算值替换的值(或大于一项的组)。因此,新列是原始列的简单副本。第一个条件可以测试并np.where应用于每一行transformdf[['delivery_ratio_filled','case_ratio_filled']] = (    df.groupby(['Node', 'DAY', 'COMMODITY_CODE'])[['deliveries_ratio','case_ratio']]      .transform(        lambda x: np.where(x.isna(), x.mean(), x)))第二个条件不需要分组df['delivery_ratio_filled'] = (  np.where(df['delivery_ratio_filled'].isna(),           1 / df['window_count'],           df['delivery_ratio_filled']))df['case_ratio_filled'] = (  np.where(df['case_ratio_filled'].isna(),           1 / df['window_count'],           df['case_ratio_filled']))df出去:     Node COMMODITY_CODE  ...  delivery_ratio_filled  case_ratio_filled0  7014.0           SCFZ  ...               0.354839           0.3578541  7014.0           SCFZ  ...               0.423077           0.4579452  7014.0           SCFZ  ...               0.258621           0.2833793  7030.0           SCDD  ...               0.300000           0.3165054  7030.0           SCDD  ...               0.232558           0.236513

梦里花落0921

也可以用dplyrpython的方式实现:>>> from datar.all import f, tribble, group_by, mutate, if_else, is_na, mean>>> >>> df = tribble(...     f.Node, f.COMMODITY_CODE, f.DAY, f.Capacity_Case,  f.Capacity_Delivery, f.case_ratio, f.delivery_ratio,  f.window_count,...     7014.0, "SCFZ",           1,     26610.0,          12.0,                0.357854,     0.354839,          3,...     7014.0, "SCFZ",           2,     25551.0,          11.0,                0.457945,     0.423077,          3,...     7014.0, "SCFZ",           3,     30669.0,          13.0,                0.283379,     0.258621,          3,...     7030.0, "SCDD",           1,     34244.0,          16.0,                0.316505,     0.300000,          4,...     7030.0, "SCDD",           2,     25954.0,          13.0,                0.236513,     0.232558,          4,... )    >>> >>> >>> df >> \...     group_by(f.Node, f.DAY, f.COMMODITY_CODE) >> \...     mutate(delivery_ratio_filled = if_else(~is_na(f.delivery_ratio),...                                            f.delivery_ratio, ...                                            mean(f.delivery_ratio)),...            case_ratio_filled = if_else(~is_na(f.case_ratio),...                                        f.case_ratio, ...                                        mean(f.case_ratio))) >> \...     mutate(delivery_ratio_filled = if_else(~is_na(f.delivery_ratio_filled),...                                            f.delivery_ratio_filled,...                                            1.0 / f.window_count),...            case_ratio_filled = if_else(~is_na(f.case_ratio_filled),...                                        f.case_ratio_filled,...                                        1.0 / f.window_count))       Node COMMODITY_CODE     DAY  Capacity_Case  Capacity_Delivery  case_ratio  delivery_ratio  window_count  delivery_ratio_filled  case_ratio_filled  <float64>       <object> <int64>      <float64>          <float64>   <float64>       <float64>       <int64>              <float64>          <float64>0    7014.0           SCFZ       1        26610.0               12.0    0.357854        0.354839             3               0.354839           0.3578541    7014.0           SCFZ       2        25551.0               11.0    0.457945        0.423077             3               0.423077           0.4579452    7014.0           SCFZ       3        30669.0               13.0    0.283379        0.258621             3               0.258621           0.2833793    7030.0           SCDD       1        34244.0               16.0    0.316505        0.300000             4               0.300000           0.3165054    7030.0           SCDD       2        25954.0               13.0    0.236513        0.232558             4               0.232558           0.236513[Groups: Node, DAY, COMMODITY_CODE (n=5)]
打开App,查看更多内容
随时随地看视频慕课网APP

相关分类

Python