pandas按列分组函数的应用

7
在 Groupby 文档中,我只看到了对轴 0 的索引或列标签应用函数进行分组的示例。我没有看到任何关于如何通过将函数应用于列来派生标签进行分组的示例。我认为可以使用 apply 进行此操作。下面的示例是否是最佳方式?
df = pd.DataFrame({'name' : np.random.choice(['a','b','c','d','e'], 20), 
               'num1': np.random.randint(low = 30, high=100, size=20),
               'num2': np.random.randint(low = -3, high=9, size=20)})

df.head()

  name  num1 num2
0   d   34  7
1   b   49  6
2   a   51  -1
3   d   79  8
4   e   72  5

def num1_greater_than_60(number_num1):
    if number_num1 >= 60:
        return 'greater'
    else:
        return 'less'

df.groupby(df['num1'].apply(num1_greater_than_60))
3个回答

5

from DataFrame.groupby() docs:

by : mapping, function, str, or iterable
    Used to determine the groups for the groupby.
    If ``by`` is a function, it's called on each value of the object's
    index. If a dict or Series is passed, the Series or dict VALUES
    will be used to determine the groups (the Series' values are first
    aligned; see ``.align()`` method). If an ndarray is passed, the
    values are used as-is determine the groups. A str or list of strs
    may be passed to group by the columns in ``self``

所以我们可以这样做:
In [35]: df.set_index('num1').groupby(num1_greater_than_60)[['name']].count()
Out[35]:
         name
greater    15
less        5

谢谢@MaxU,我试图在不将列设置为索引的情况下完成它,因为它们可能不是唯一的。或者这无关紧要吗? - dleal
@dleal,请问您能发布一下您想要的数据集吗? - MaxU - stand with Ukraine
我试图尽可能地通用。也许我应该更改示例,使它更清楚,我试图分组的列具有重复的值? - dleal
@dleal,在这种情况下,索引的唯一性并不重要。 - MaxU - stand with Ukraine

2
您可以在此处不使用申请。
df.groupby(df.num1.gt(60))

df.num1.gt(60)
Out[774]: 
0      True
1      True
2      True
3      True
4     False
5      True
6      True
7      True
8     False
9      True
10    False
11     True
12     True
13     True
14    False
15     True
16    False
17    False
18     True
19    False
Name: num1, dtype: bool

1
这是正确的,但我只是想举一个简单函数的例子。一般来说,该函数可能不是可用方法之一。 - dleal
我认为使用自定义函数而不是内置的gt函数的示例将更有帮助,也可能更加复杂。 - mins

1
通常我会通过创建一个派生列来进行分组,这样更容易跟踪,并且最后可以删除它或仅选择所需的列。
df = pd.DataFrame({'name' : np.random.choice(['a','b','c','d','e'], 20), 
               'num1': np.random.randint(low = 30, high=100, size=20),
               'num2': np.random.randint(low = -3, high=9, size=20)})

df['num1_greater_than_60'] = df['num1'].gt(60).replace(
    to_replace=[True, False], 
    value=['greater', 'less'])

df.groupby('num1_greater_than_60').dosomething()

谢谢@Ken_Syme,这也是我通常做的事情,但我想知道是否有除了创建人工列之外的其他方法。 - dleal

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接