【问题标题】:Pandas if/then aggregationPandas if/then 聚合
【发布时间】:2018-01-22 18:27:27
【问题描述】:

我一直在搜索,但还没有弄清楚。希望有人可以帮助这个python新手解决我的问题。

我试图弄清楚如何在 python 中编写 if/then 语句并对该 if/then 语句执行聚合。我的最终目标是说如果日期 = 1/7/2017 然后使用“假”列中的值。如果 date = all else 然后将两列平均在一起。

这是我目前所拥有的:

import pandas as pd
import numpy as np
import datetime

np.random.seed(42)
dte=pd.date_range(start=datetime.date(2017,1,1), end= datetime.date(2017,1,15))
fake=np.random.randint(15,100, size=15)
fake2=np.random.randint(300,1000,size=15)

so_df=pd.DataFrame({'date':dte,
             'fake':fake,
             'fake2':fake2})

so_df['avg']= so_df[['fake','fake2']].mean(axis=1)
so_df.head()

【问题讨论】:

    标签: python pandas numpy aggregation


    【解决方案1】:

    假设您已经计算了平均列:

    so_df['fake'].where(so_df['date']=='20170107', so_df['avg'])
    Out: 
    0     375.5
    1     260.0
    2     331.0
    3     267.5
    4     397.0
    5     355.0
    6      89.0
    7     320.5
    8     449.0
    9     395.5
    10    197.0
    11    438.5
    12    498.5
    13    409.5
    14    525.5
    Name: fake, dtype: float64
    

    如果没有,可以用同样的计算替换列引用:

    so_df['fake'].where(so_df['date']=='20170107', so_df[['fake','fake2']].mean(axis=1))
    

    要检查多个日期,您需要使用 or 运算符的逐元素版本(即管道:|)。否则会报错。

    so_df['fake'].where((so_df['date']=='20170107') | (so_df['date']=='20170109'), so_df['avg'])
    

    上述检查两个日期。在 3 个或更多的情况下,您可能希望将isin 与列表一起使用:

    so_df['fake'].where(so_df['date'].isin(['20170107', '20170109', '20170112']), so_df['avg'])
    Out[42]: 
    0     375.5
    1     260.0
    2     331.0
    3     267.5
    4     397.0
    5     355.0
    6      89.0
    7     320.5
    8      38.0
    9     395.5
    10    197.0
    11     67.0
    12    498.5
    13    409.5
    14    525.5
    Name: fake, dtype: float64
    

    【讨论】:

    • 谢谢!这些都非常有帮助。如果我想做超过 1 个日期,即 1/7、1/9 和 1/11,我可以简单地将其写为 so_df['fake'].where((so_df['date']=='20170107') or(so_df['date']=='20170105') or (so_df['date']=='20170111'), so_df[['fake','fake2']].mean(axis=1))
    • @P.Cummings 不幸的是,您不能将 or 用于 pandas 数据结构。您需要使用按位或 (|) 的元素重载版本。我在帖子中添加了几个示例。
    • 谢谢。这很有帮助!
    【解决方案2】:

    让我们使用np.where:

    so_df['avg'] = np.where(so_df['date'] == pd.to_datetime('2017-01-07'), 
                            so_df['fake'], so_df[['fake',
                            'fake2']].mean(1))
    

    输出:

             date  fake  fake2    avg
    0  2017-01-01    66    685  375.5
    1  2017-01-02    29    491  260.0
    2  2017-01-03    86    576  331.0
    3  2017-01-04    75    460  267.5
    4  2017-01-05    35    759  397.0
    5  2017-01-06    97    613  355.0
    6  2017-01-07    89    321   89.0
    7  2017-01-08    89    552  320.5
    8  2017-01-09    38    860  449.0
    9  2017-01-10    17    774  395.5
    10 2017-01-11    36    358  197.0
    11 2017-01-12    67    810  438.5
    12 2017-01-13    16    981  498.5
    13 2017-01-14    44    775  409.5
    14 2017-01-15    52    999  525.5
    

    【讨论】:

      【解决方案3】:

      在 pandas 中执行 if-else 的一种方法是使用 np.where 里面有三个值,condition,if,else

      so_df['avg']= np.where(so_df['date'] == '2017-01-07',so_df['fake'],so_df[['fake','fake2']].mean(axis=1))
      
          date        fake    fake2   avg
      0   2017-01-01  66      685 375.5
      1   2017-01-02  29      491 260.0
      2   2017-01-03  86      576 331.0
      3   2017-01-04  75      460 267.5
      4   2017-01-05  35      759 397.0
      5   2017-01-06  97      613 355.0
      6   2017-01-07  89      321 89.0
      7   2017-01-08  89      552 320.5
      8   2017-01-09  38      860 449.0
      9   2017-01-10  17      774 395.5
      10  2017-01-11  36      358 197.0
      11  2017-01-12  67      810 438.5
      12  2017-01-13  16      981 498.5
      13  2017-01-14  44      775 409.5
      14  2017-01-15  52      999 525.5
      

      【讨论】:

        【解决方案4】:

        我们也可以使用Series.where()方法:

        In [141]: so_df['avg'] = so_df['fake'] \
             ...:                   .where(so_df['date'].isin(['2017-01-07','2017-01-09']))
             ...:                   .fillna(so_df[['fake','fake2']].mean(1))
             ...:
        
        In [142]: so_df
        Out[142]:
                 date  fake  fake2    avg
        0  2017-01-01    66    685  375.5
        1  2017-01-02    29    491  260.0
        2  2017-01-03    86    576  331.0
        3  2017-01-04    75    460  267.5
        4  2017-01-05    35    759  397.0
        5  2017-01-06    97    613  355.0
        6  2017-01-07    89    321   89.0
        7  2017-01-08    89    552  320.5
        8  2017-01-09    38    860   38.0
        9  2017-01-10    17    774  395.5
        10 2017-01-11    36    358  197.0
        11 2017-01-12    67    810  438.5
        12 2017-01-13    16    981  498.5
        13 2017-01-14    44    775  409.5
        14 2017-01-15    52    999  525.5
        

        【讨论】:

          猜你喜欢
          • 2018-10-24
          • 2021-10-03
          • 1970-01-01
          • 2021-12-05
          • 1970-01-01
          • 2019-02-25
          • 2021-08-24
          • 2019-05-15
          相关资源
          最近更新 更多