【问题标题】:Using Pandas to Find Minimum Values of Grouped Rows使用 Pandas 查找分组行的最小值
【发布时间】:2017-05-17 23:38:39
【问题描述】:

这可能是一个微不足道的问题,但我仍在尝试找出 pandas/numpy。

所以,假设我有一个具有以下结构的表:

group_id | col1 | col2 | col3 |  "A"   |  "B"
   x     |   1  |   2  |  3   |  NaN   |   1
   x     |   3  |   2  |  3   |   1    |   1 
   x     |   4  |   2  |  3   |   2    |   1
   y     |   1  |   2  |  3   |  NaN   |   3 
   y     |   3  |   2  |  3   |   3    |   3 
   z     |   3  |   2  |  3   |   10   |   2
   z     |   2  |   2  |  3   |   6    |   2
   z     |   4  |   2  |  3   |   4    |   2
   z     |   4  |   2  |  3   |   2    |   2

请注意,有一个 group_id 用于对每一行中的元素进行分组。 所以一开始,我有 group_id 和 col1-col3 列的值。

然后对于每一行,如果 col1、col2 或 col3 的值 = 1,则“A”为 NaN,否则该值基于公式(与此处无关,因此我放置了一些数字)。

那个,我知道怎么用:

df["A"] = np.where(((df['col1'] == 1)|(df['col2']== 1) | (df['col3']) == 1))), NaN, value)

但是对于“B”列,我需要用 A 列中特定组的最小值来填充它。

例如,对于具有组 X 的所有行,“B”等于“1”,因为对于所有组“x”行,A 列中的最小值等于 1。

同样,对于“y”组中的行,最小值为 3,而对于“z”组,最小值为 2。我该如何使用 pandas...?这让我有点困惑,因为特定组的行数可以是不同的大小。

如果它们的大小都相同,我只能说用预设范围内的最小值填充它。

我希望这是有道理的;请让我知道我是否应该提供更清晰的示例或澄清任何事情!

【问题讨论】:

    标签: python pandas numpy dataframe


    【解决方案1】:
    • 只关注['col1', 'col2', 'col3']
    • 查看它们是否等于1eq(1) 等于== 1
    • 查看axis=1any(1) 是否有任何等于一
    • 使用loc进行分配

    anyone = df[['col1', 'col2', 'col3']].eq(1).any(1)
    df.loc[anyone, 'A'] = np.nan
    

    numpy 等效

    anyone = (df[['col1', 'col2', 'col3']].values == 1).any(1)
    df.A = np.where(anyone, np.nan, df.A)
    

    【讨论】:

    • 那么,我使用 np.where 解决我的那部分问题的方法不起作用吗?或者您是否建议使用 .loc 使其更优雅(而不是手动检查)?
    • 嗯,你为什么使用.all(1)?我只关心是否有任何一列 = 1,而不是所有列。 .eq(1) 不够吗?
    • 我明白了;我将更新我的代码以使用 .any(1);它看起来比手动检查每一列更干净。关于填写 B 列值的另一个问题,使用 groupby 的技巧是什么?
    • 所以,我应该可以说:df.loc[anyone, 'A'] = np.nan 如果有 1,则将 'A' 设置为 NaN。但对于所有列的条目除了 1 之外还有其他值,说 df.loc[!anyone, 'A'] = value 会起作用,对吧?
    【解决方案2】:

    要获得每个组的 A 列的最小值,请使用 transform

    df.groupby('group_id')['A'].transform('min')
    

    【讨论】:

    • 我理解正确,对于每一行,这将找到 group_id,然后使用该 group_id 对所有行进行分组。然后 .transform('min') 告诉我们正在尝试找到该组中的最小值。那么如果我想最小化该组的“A”列中的值,它会是 df['B'] = df.groupby('group_id').transform('min').min("A") 吗?我假设这将自动忽略 "A" 中的任何值,即 NaN
    • 不需要输入.min('A')。我写的上面的代码中只使用了“A”列。它在groupby 语句之后的括号中。你写的其他一切都是正确的。
    • 啊,我明白了。这就说得通了;我不知道变换('min')。谢谢!
    • 如此清晰 - 转换返回一个对象,每个组的行数相同。所以它保持原始数据框行尺寸相同。
    • 您指的是列吗?如果它返回相同的行数就没有意义吗?有些组可能有 15 行,而其他组可能有 2 行。它只选择最大的吗?
    【解决方案3】:
    df.groupby('group_id')['A'].min()
    

    【讨论】:

    • the accepted answer 中使用的transform('min') 语法相比,min() 语法有什么好处?
    猜你喜欢
    • 2021-05-23
    • 1970-01-01
    • 2021-01-15
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-12-09
    • 2014-02-17
    • 2021-06-17
    相关资源
    最近更新 更多