【问题标题】:Pandas replace last item in groupby if NaN with another colum如果 NaN 用另一列替换,Pandas 将组中的最后一项替换
【发布时间】:2020-11-26 02:46:34
【问题描述】:

我试图用另一列的值替换组中的最后一行,只有当它为空时。我可以分别完成这两部分,但似乎无法将它们结合起来。有人有什么想法吗?

这些是单独的部分:

# replace any NaN values with values from 'target'
df.loc[df['target'].isnull(),'target'] = df['value']

# replace last value in groupby with value from 'target'
df.loc[df.groupby('id').tail(1).index,'target'] = df['value']

原始数据:

    date        id      value       target
0   2020-08-07  id01    0.100775    NaN
1   2020-08-08  id01    0.215885    0.215885
2   2020-08-09  id01    0.012154    0.012154
3   2020-08-10  id01    0.374503    NaN
4   2020-08-07  id02    0.369707    0.369707
5   2020-08-08  id02    0.676743    0.676743
6   2020-08-09  id02    0.659521    0.659521
7   2020-08-10  id02    0.799071    NaN

将 groupby('id') 中最后一行的 'target' 列替换为 'value' 中的内容:

    date        id      value       target
0   2020-08-07  id01    0.100775    NaN
1   2020-08-08  id01    0.215885    0.215885
2   2020-08-09  id01    0.012154    0.012154
3   2020-08-10  id01    0.374503    0.374503
4   2020-08-07  id02    0.369707    0.369707
5   2020-08-08  id02    0.676743    0.676743
6   2020-08-09  id02    0.659521    0.659521
7   2020-08-10  id02    0.799071    0.799071

【问题讨论】:

    标签: python pandas time-series pandas-groupby


    【解决方案1】:

    使用 combine_first,您会被各种选择宠坏。

    第一选择

    .groupby()nth(value) 一起使用

    m=df.groupby('id',as_index=False).nth(-1).index#mask each last value in the group
    df.loc[m, 'target'] = df['target'].combine_first(df['value'])populate value
    

    第二个选项

    使用combine_first 使用.iloc 访问器获取target 列和value 列中的最后一个值groupby

         df.groupby('id').apply(lambda x:(x.iloc[-1:,3].combine_first(x.iloc[-1:,2])))\
    .reset_index(level=0).combine_first(df)
    

    第三个选项

    选择每个组中的最后一个索引。根据需要填充列目标并使用 combine_first 更新 df

    g=df.groupby('id').apply(lambda x:x.iloc[-1:]).reset_index(level=0, drop=True)
    #df.loc[g, 'target'] = df['target'].combine_first(df['value'])
    g.target=g.value
    g.combine_first(df)
    
    
    
       date    id     value    target
    0  2020-08-07  id01  0.100775       NaN
    1  2020-08-08  id01  0.215885  0.215885
    2  2020-08-09  id01  0.012154  0.012154
    3  2020-08-10  id01  0.374503  0.374503
    4  2020-08-07  id02  0.369707  0.369707
    5  2020-08-08  id02  0.676743  0.676743
    6  2020-08-09  id02  0.659521  0.659521
    7  2020-08-10  id02  0.799071  0.799071
    

    【讨论】:

    • @dingo 这有帮助吗?很高兴为您提供进一步的帮助
    【解决方案2】:

    groupby() 中查找最后一个目标 的索引,然后使用.combine_first() 仅替换空值

    indexes = df.groupby('id').tail(1).index
    df.loc[indexes, 'target'] = df['target'].combine_first(df['value'])
    #result
        date        id      value       target
    0   2020-08-07  id01    0.100775    NaN
    1   2020-08-08  id01    0.215885    0.215885
    2   2020-08-09  id01    0.012154    0.012154
    3   2020-08-10  id01    0.374503    0.374503
    4   2020-08-07  id02    0.369707    0.369707
    5   2020-08-08  id02    0.676743    0.676743
    6   2020-08-09  id02    0.659521    0.659521
    7   2020-08-10  id02    0.799071    0.799071
    

    【讨论】:

      【解决方案3】:

      fillna 在整个列上,但如果它不是每个“id”的最后一个缺失,则掩码回NaN

      m = df['target'].isnull() & df['id'].duplicated(keep='last')
      df['target'] = df['target'].fillna(df['value']).mask(m)
      

               date    id     value    target
      0  2020-08-07  id01  0.100775       NaN
      1  2020-08-08  id01  0.215885  0.215885
      2  2020-08-09  id01  0.012154  0.012154
      3  2020-08-10  id01  0.374503  0.374503
      4  2020-08-07  id02  0.369707  0.369707
      5  2020-08-08  id02  0.676743  0.676743
      6  2020-08-09  id02  0.659521  0.659521
      7  2020-08-10  id02  0.799071  0.799071
      

      【讨论】:

        【解决方案4】:

        这应该可以。添加了tail 变量只是为了便于阅读语法:

        tail = df.groupby('id').tail(1)
        df.loc[tail.index,'target'] = df.loc[tail.index]['target'].fillna(tail.value) 
        

        输出:

        0 idx        date    id     value    target
        1   0  2020-08-07  id01  0.100775       NaN
        2   1  2020-08-08  id01  0.215885  0.215885
        3   2  2020-08-09  id01  0.012154  0.012154
        4   3  2020-08-10  id01  0.374503  0.374503
        5   4  2020-08-07  id02  0.369707  0.369707
        6   5  2020-08-08  id02  0.676743  0.676743
        7   6  2020-08-09  id02  0.659521  0.659521
        8   7  2020-08-10  id02  0.799071  0.799071
        

        【讨论】:

          猜你喜欢
          • 2017-08-25
          • 1970-01-01
          • 2021-09-24
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2017-08-14
          • 1970-01-01
          • 2019-07-16
          相关资源
          最近更新 更多