Pandas groupby 如何计算区间计数

25 投票
2 回答
42379 浏览
提问于 2025-04-18 15:09

假设我有一个很大的数字列表,这些数字在0到100之间。我会根据最大数字来计算范围,然后把这些范围分成10个区间。所以我的范围可能是这样的:

ranges = [0,10,20,30,40,50,60,70,80,90,100]

接下来,我会统计每个区间内的数字出现次数,比如0-10这个区间、10-20这个区间,依此类推。我会遍历列表中的每一个数字,检查它属于哪个区间。我觉得这样做在运行速度上可能不是最优的。

我能不能通过使用pandas,比如用pandas.groupby,来加快这个过程呢?如果可以的话,应该怎么做呢?

2 个回答

36

我很惊讶还没看到这个,所以不多说了,下面是

.value_counts(bins=N)

使用 pd.cut 来计算区间,然后再用 groupBy 是一个两步的过程。而 value_counts 让你可以通过 bins 参数来简化这个过程:

# Uses Ed Chum's setup. Cross check our answers match!
np.random.seed(0)
df = pd.DataFrame({"a": np.random.random_integers(1, high=100, size=100)})

df['a'].value_counts(bins=10, sort=False)

(0.9, 10.9]      11
(10.9, 20.8]     10
(20.8, 30.7]      8
(30.7, 40.6]     13
(40.6, 50.5]     11
(50.5, 60.4]      9
(60.4, 70.3]     10
(70.3, 80.2]     11
(80.2, 90.1]     13
(90.1, 100.0]     4
Name: a, dtype: int64

这会创建10个均匀间隔的右闭合区间,并对你的数据进行计数。如果你想避免 value_counts 按照计数从大到小排序,就需要加上 sort=False


按不等范围分组

如果你想按不等的范围来分组,可以给 bins 参数传递一个列表:

bins = [0, 10, 20, 30, 40, 50, 60, 70, 80, 90, 100]
df['a'].value_counts(bins=bins, sort=False) 

(-0.001, 10.0]    11
(10.0, 20.0]      10
(20.0, 30.0]       8
(30.0, 40.0]      13
(40.0, 50.0]      11
(50.0, 60.0]       9
(60.0, 70.0]      10
(70.0, 80.0]      11
(80.0, 90.0]      13
(90.0, 100.0]      4
Name: a, dtype: int64
41

我们可以使用 pd.cut 这个功能把数值分成几个区间,然后可以用 groupby 来对这些区间进行分组,最后再用 count 来统计每个区间里的数值数量:

np.random.seed(0)
df = pd.DataFrame({"a": np.random.random_integers(1, high=100, size=100)})
ranges = [0,10,20,30,40,50,60,70,80,90,100]
df.groupby(pd.cut(df.a, ranges)).count()

            a
a            
(0, 10]    11
(10, 20]   10
(20, 30]    8
(30, 40]   13
(40, 50]   11
(50, 60]    9
(60, 70]   10
(70, 80]   11
(80, 90]   13
(90, 100]   4

撰写回答