【问题标题】:Pandas groupby and filter by conditional check on rowsPandas groupby 并通过对行的条件检查进行过滤
【发布时间】:2020-06-26 09:28:20
【问题描述】:

我有一个熊猫数据框,df:

id year variable value
1   19   high     20
1   19   low      10
1   20   high     20
1   20   low      30

我想通过 id 和 year 进行分组(每个这样的组只有 2 行,一个代表 high,另一个代表 low),并检查 high 变量的值是否实际上大于 low 变量的值。如果没有,那么我想删除这些组并将它们放入一个新的数据框中。所以对于上面我想要的,df:

id year variable value
1   19   high     20
1   19   low      10

df2:

id year variable value
1   20   high     20
1   20   low      30

【问题讨论】:

    标签: python pandas dataframe pandas-groupby


    【解决方案1】:

    我们可以使用groupbydiff 来测试是否较低>= 较高。

    s = df.groupby(['id','year','variable']).first().unstack(-1).sort_index(axis=1)
    #sort index is to order the columns. 
    df_new = s[s.diff(axis=1).ge(0).any(1)].stack(1).reset_index()
    
    print(df_new)
    
       id  year variable  value
    0   1    20     high     20
    1   1    20      low     30
    

    【讨论】:

    • 您好 Datanovice。 unstack(-1) 到底在做什么?好像是把列转换成多索引列?
    【解决方案2】:

    下面的代码无需 groupby 即可解决。它改为旋转变量,然后比较高和低,只保留那些高>低的列,然后再次取消旋转它们

    df.pivot_table(index=['id','year'],columns='variable', values='value').reset_index().query('high>low').melt(id_vars=['id','year'],value_vars=['high','low'])
    
    id  year    variable    value
    0   1   19  high    20
    1   1   19  low     10
    

    第二个数据框只会将 high>low 替换为 low>=high

    【讨论】:

      【解决方案3】:

      重新创建您的 DataFrame

      df = pd.DataFrame(
          {
              "id": 1,
              "year": [19, 19, 20, 20],
              "variable": ["high", "low", "high", "low"],
              "value": [20, 10, 20, 30],
          }
      )
      

      遍历 groupby 组和过滤器:

      df_res = []
      df_res2 = []
      for _, df_group in df.groupby(["id", "year"]):
      
          val_low = df_group.query("variable == 'low'").value.values[0]
          val_high = df_group.query("variable == 'high'").value.values[0]
      
          if val_high > val_low:
              df_res.append(df_group)
          else:
              df_res2.append(df_group)
      
      df_res = pd.concat(df_res)
      df_res2 = pd.concat(df_res2)
      
      print(df_res)
      id year variable value
      1   19   high     20
      1   19   low      10
      
      print(df_res2)
      id year variable value
      1   20   high     20
      1   20   low      30
      

      【讨论】:

        【解决方案4】:

        初学者:

        创建 2 个 df,其中包含“变量”值的高低:

        dfh = df[df["var"]=="high"]
        dfh.reset_index(drop=True, inplace=True)
        
        dfl = df[df["var"]=="low"]
        dfl.reset_index( drop=True, inplace=True)
        

        进行检查并将结果放入新列中:

        dfh['greatest'] = np.where(dfh['val'] > dfl['val'], 'True', 'False')
        dfl['greatest'] = np.where(dfl['val'] < dfh['val'], 'True', 'False')
        

        合并这两个 dfs:

        dfall = pd.concat([dfh,dfl])
        

        最后通过选择有趣的值来创建 dfs:

        df_great = dfall[dfall["greatest"]=="True"]
        df_less = dfall[dfall["greatest"]=="False"]
        

        【讨论】:

          猜你喜欢
          • 2022-10-14
          • 2018-07-22
          • 2021-02-04
          • 2020-10-10
          • 2016-11-04
          • 2022-11-16
          • 2022-11-03
          • 1970-01-01
          • 2017-01-20
          相关资源
          最近更新 更多