当前位置: 首页 > 知识库问答 >
问题:

Python基于列和get max进行分组,但基于另一列进行排除

艾骏喆
2023-03-14

我正在处理一些数据,并希望将某个列的最大值按不同的列分组。但是,我想根据另一列从最大计算中排除某些行。

示例:

df = pd.DataFrame({'Col1':['A','A','A','B','B','B','B'],
                   'Col2':['Build','Plan','Other','Test','Build','Other','Buy'],
                   'Col3':[2,5,17,5,13,12,12]})

我想得到Col3的最大值,按Col1分组,同时排除Col2中包含“Other”的任何行。因此,“A”的Col3的最大值应该是5,而不是17。

我能够使用:df['new']=df获得Col1分组的Col3的最大值。groupby(['Col1'])['Col3']。transform(max)但是,对于a,这将给我一个17的值。

通过查看其他线程,我尝试使用:

x = df1.groupby(['Col1'])
x2 = x.apply(lambda g: g[g['Col2'] != 'Other'])

这似乎让我接近了(它将数据按Col1分组,并根据Col2删除了行)。然而,我似乎再也找不到一种基于Col1获得Col3最大值的方法了。

我最多只能使用:x2['Col3']。max()在删除Col2中包含“Other”的所有行后,获取Col3的最大值。但是,我无法获得按Col1分组的Col3的最大值。

我想知道是否有一种方法可以使用内置的熊猫函数来相对简单地完成这一点,而不是创建一个全新的定制函数?

共有3个答案

芮博厚
2023-03-14

@Vaishali的答案是一个很好的开始,但我认为它可能会有一些问题,特别是在应用ffill来去除na时。要使此方法起作用,您需要以更具体的方式对数据帧进行排序。要让人信服,请尝试以下方法:

df = pd.DataFrame({'Col1':['A','A','A','B','B','B','B',"C", "C"],
               'Col2':['Build','Plan','Other','Test','Build','Other','Buy', "Buy","Other"],
               'Col3':[2,5,17,5,13,12,12,14,5]})
df = df.sample(frac=1) #shuffle rows

df['new']=df[df.Col2 != 'Other'].groupby('Col1')["Col3"].transform('max')
df['new'] = df.new.ffill()

你可以得到这个不好的结果。

Col1    Col2    Col3    new
3   B   Test    5   13.0
7   C   Buy     14  14.0
6   B   Buy     12  13.0
1   A   Plan    5   5.0
0   A   Build   2   5.0
5   B   Other   12  5.0
8   C   Other   5   5.0
4   B   Build   13  13.0
2   A   Other   17  13.0

更好的解决方案是:首先定义这个函数。

def new_transform(df, exclude_cond,gbycol,target, agg_fun, ignore_value=None):
    df['target_temp'] = df[target] 
    df.loc[eval(exclude_cond), 'target_temp'] = ignore_value
    tmp=df.groupby(gbycol)['target_temp'].transform(agg_fun)
    df.drop('target_temp', axis=1, inplace=True)
    return tmp

它将把你的数据框,你的exculde_cond作为字符串,你的Groupby作为字符串或字符串的列表,目标:我们计算操作的列名,聚合函数和一个被聚合函数忽略的值(没有一个对主要的agg函数有效)。

例子:

df = pd.DataFrame({'Col1':['A','A','A','B','B','B','B',"C", "C"],
                   'Col2':['Build','Plan','Other','Test','Build','Other','Buy', "Buy","Other"],
                   'Col3':[2,5,17,5,13,12,12,14,5]})
df = df.sample(frac=1)
df['new']=new_transform(df, "df['Col2']=='Build'", ['Col1'],'Col3', 'sum', np.nan)

我们得到正确的计算:

  Col1  Col2    Col3    new
3   B   Test    5     29.0
2   A   Other   17    22.0
4   B   Build   13    29.0
6   B   Buy     12    29.0
7   C   Buy     14    19.0
1   A   Plan    5     22.0
5   B   Other   12    29.0
0   A   Build   2     22.0
8   C   Other   5     19.0
范华清
2023-03-14

使用Groupby混合它的另一种方法

df.groupby([df.Col2.ne('Other'), 'Col1']).Col3.max()[True]

Col1
A     5
B    13
Name: Col3, dtype: int64
盖锦程
2023-03-14

你可以试试

df[df.Col2 != 'Other'].groupby('Col1').Col3.max()

Col1
A     5
B    13

要创建新列,请执行以下操作:

df['new']=df[df.Col2 != 'Other'].groupby('Col1').Col3.transform('max')
df['new'] = df.new.ffill()

    Col1    Col2    Col3    new
0   A       Build   2       5.0
1   A       Plan    5       5.0
2   A       Other   17      5.0
3   B       Test    5       13.0
4   B       Build   13      13.0
5   B       Other   12      13.0
6   B       Buy     12      13.0

说明:仅选择Col2值不等于“其他”的df行,按Col1分组,查找Col3的最大值。

下面是transform的文档:它返回一个带有转换值的类似索引df,而不是聚合。

 类似资料:
  • 我有一个自定义类数据列表,我想根据一个字段和值应该是另一个字段对它们进行分组。以下面的例子为例。 现在我想基于类对这些数据进行分组。预期的输出应该是一个映射,其中包含作为类的键和作为学生姓名列表的值。 我的代码是这样的:

  • 问题内容: 在PHP中可以做这样的事情吗?您将如何编写函数?这是一个例子。顺序是最重要的。 我想做类似的事情 因为最后我使用了foreach()并且它们的顺序不正确(因为我将值附加到需要正确顺序的字符串中,而且我事先也不知道所有的数组键/值)。 我看过PHP的内部数组函数,但似乎只能按字母或数字排序。 问题答案: 只需使用或即可。通过以给定的数组(按正确的顺序)开始并用实际数组中的数据覆盖/添加键

  • 我的数据集示例如下: 我对这个数据集有两个问题: < li >我需要计算日期之间的差异,但此差异将基于“买方”和“id”分组来计算,这意味着,买方“Jenny”和Id“9”的日期差异将是一个组,Id为“4”的买方“Chang”将是另一个组,Id为“5”的买方“Chunfei”将是另一个组,Id为“8”的“Chunfei”将是另一个组。因此,输出将是: 问题是我不明白为什么group_by不起作用。

  • 我有一个带有key_number列的数据帧df1,以及带有key_number和日期列的数据帧df2。如何将date的值分配为df1中的新列,但与键号相关联?当使用loc时,它根据顺序分配值,导致df1中错误的行(键的错误日期)。此外,数据帧具有不同的形状,因此我在df1中保留了空值。 提前感谢:)

  • 如何根据列上的0到max(int)值自动递增列。 假设,我希望增量从$0开始。我必须为此代码编辑什么? 进入