【问题标题】:Pandas - Groupby with conditional formulaPandas - 带条件公式的 Groupby
【发布时间】:2017-12-18 09:01:48
【问题描述】:
   Survived  SibSp  Parch
0         0      1      0
1         1      1      0
2         1      0      0
3         1      1      0
4         0      0      1

鉴于上述数据框,有没有一种优雅的方式来groupby 有条件? 我想根据以下条件将数据分成两组:

(df['SibSp'] > 0) | (df['Parch'] > 0) =   New Group -"Has Family"
 (df['SibSp'] == 0) & (df['Parch'] == 0) = New Group - "No Family"

然后采用这两个组的方法,最终得到如下输出:

               SurvivedMean
 Has Family    Mean
 No Family     Mean

可以使用 groupby 来完成,还是必须使用上述条件语句追加一个新列?

【问题讨论】:

  • 这看起来像是布尔索引的工作。
  • 你的df是用二进制编码的吗?如果是这样,您也许可以使用 pandas 方法 get_dummies {pandas.pydata.org/pandas-docs/stable/generated/…}。否则,是的,我建议/认为您应该创建一个新列(我认为您只需要一个)来执行 groupby。如果我对您在做什么有更好的了解,我可以帮助编写一些代码!此外,鉴于您想要的输出,您似乎也需要旋转数据库!

标签: python pandas dataframe conditional-statements pandas-groupby


【解决方案1】:

一种简单的分组方法是使用这两列的总和。如果其中任何一个为正,则结果将大于 1。并且 groupby 接受任意数组,只要长度与 DataFrame 的长度相同,因此您无需添加新列。

family = np.where((df['SibSp'] + df['Parch']) >= 1 , 'Has Family', 'No Family')
df.groupby(family)['Survived'].mean()
Out: 
Has Family    0.5
No Family     1.0
Name: Survived, dtype: float64

【讨论】:

    【解决方案2】:

    如果SibSpParch 列中的值从未小于0,则仅使用一个条件:

    m1 = (df['SibSp'] > 0) | (df['Parch'] > 0)
    
    df = df.groupby(np.where(m1, 'Has Family', 'No Family'))['Survived'].mean()
    print (df)
    Has Family    0.5
    No Family     1.0
    Name: Survived, dtype: float64
    

    如果不可能,请先使用两个条件:

    m1 = (df['SibSp'] > 0) | (df['Parch'] > 0)
    m2 = (df['SibSp'] == 0) & (df['Parch'] == 0)
    a = np.where(m1, 'Has Family', 
        np.where(m2, 'No Family', 'Not'))
    
    df = df.groupby(a)['Survived'].mean()
    print (df)
    Has Family    0.5
    No Family     1.0
    Name: Survived, dtype: float64
    

    【讨论】:

      【解决方案3】:

      您可以在列表中定义您的条件,并使用下面的函数group_by_condition 为每个条件创建一个过滤列表。之后,您可以使用模式匹配选择结果项目:

      df = [
        {"Survived": 0, "SibSp": 1, "Parch": 0},
        {"Survived": 1, "SibSp": 1, "Parch": 0},
        {"Survived": 1, "SibSp": 0, "Parch": 0}]
      
      conditions = [
        lambda x: (x['SibSp'] > 0) or (x['Parch'] > 0),  # has family
        lambda x: (x['SibSp'] == 0) and (x['Parch'] == 0)  # no family
      ]
      
      def group_by_condition(l, conditions):
          return [[item for item in l if condition(item)] for condition in conditions]
      
      [has_family, no_family] = group_by_condition(df, conditions)
      

      【讨论】:

        猜你喜欢
        • 2021-10-25
        • 2021-04-30
        • 1970-01-01
        • 1970-01-01
        • 2020-10-05
        • 2020-02-22
        • 2020-05-31
        • 1970-01-01
        • 2018-07-22
        相关资源
        最近更新 更多