Pandas DataFrame groupby方法的完整指南

1,060 阅读8分钟

Pandas DataFrame groupby()方法用于根据标准将特定数据集的数据分割成组。groupby()函数在任何一个轴上分割数据。

Pandas groupby

Pandas groupby()是一个内置的库方法,用于根据特定的指标将数据对象分成系列(列)或DataFrames(系列的一组)。

Python中的groupby使数据集的管理更容易,因为你可以把相关的记录放到组中。

Pandas DataFrame groupby()函数涉及到对象的分割,应用一些函数,然后合并结果。它通常是在最后一组数据上完成的,以便对数据进行分组,并从数据中取出有意义的见解。

让我们看一下df.groupby()方法本身:

import pandas as pd

dataset = {
    'Name': ['Rohit', 'Arun', 'Sohit', 'Arun', 'Shubh'],
    'Roll no': ['01', '02', '03', '04', '05'],
    'maths': ['93', '63', '74', '94', '83'],
    'science': ['88', '55', '66', '94', '35'],
    'english': ['93', '74', '84', '92', '87']}

df = pd.DataFrame(dataset)
by_name = df.groupby(['Name'])
print(by_name)

输出

<pandas.core.groupby.generic.DataFrameGroupBy object at 0x10e965250>

在输出中,DataFrameGroupBy是什么东西?它是一个.__str__(),并没有给你太多关于它是什么或它如何工作的信息。DataFrameGroupBy对象之所以会让你难以理解,是因为它很懒惰。它不会做任何操作来产生一个有用的结果,直到你这么说。

一个经常与.groupby()方法一起使用的术语是split-apply-combine。这指的是下面三个步骤的链条:

  1. 一个DataFrame分割成组
  2. 对每个小的DataFrame应用一些操作
  3. 合并结果

检查df.groupby("Name")可能很有挑战性,因为在你对结果对象进行操作之前,它几乎不做这些事情。同样,Pandas GroupBy对象是懒惰的。它几乎推迟了分割-应用-合并过程中的任何部分,直到你对它调用一个方法。

那么,如果你不能看到它们中的任何一个孤立地发生,你怎么能把分裂、应用和合并阶段分开呢?检查Pandas GroupBy对象并看到拆分过程的一个有用方法是通过它进行迭代。这在DataFrameGroupBy.__iter__()中实现,为DataFrame 输出一个 (group, DataFrame) 对的迭代器:

import pandas as pd

dataset = {
    'Name': ['Rohit', 'Arun', 'Sohit', 'Arun', 'Shubh'],
    'Roll no': ['01', '02', '03', '04', '05'],
    'maths': ['93', '63', '74', '94', '83'],
    'science': ['88', '55'a '66', '94', '35'],
    'english': ['93', '74', '84', '92', '87']}

df = pd.DataFrame(dataset)
by_name = df.groupby(['Name'])

for Name, maths in by_name:
    print(f"First 2 entries for {Name!r}")
    print("------------------------")
    print(maths.head(2), end="\n\n")

输出

First 2 entries for 'Arun'
------------------------
   Name Roll no maths science english
1  Arun      02    63      55      74
3  Arun      04    94      94      92

First 2 entries for 'Rohit'
------------------------
    Name Roll no maths science english
0  Rohit      01    93      88      93

First 2 entries for 'Shubh'
------------------------
    Name Roll no maths science english
4  Shubh      05    83      35      87

First 2 entries for 'Sohit'
------------------------
    Name Roll no maths science english
2  Sohit      03    74      66      84

如果你正在研究困难的聚合问题,那么在Pandas GroupBy对象上迭代可以是一个相当大的方式来可视化分割-应用-合并的分割部分。

很少有其他的方法和属性可以让你查看各个组和它们的拆分。.groups属性会给你**{组名:组标签}**对的字典。

现在,让我们再来看看它的语法。

语法

DataFrame.groupby(by=None, axis=0, level=None, as_index=True, sort=True, group_keys=True, squeeze=False, **kwargs)

参数

groupby()函数包含7个参数:

  1. by:它用于确定**groupby()**函数的组别。它的默认值是无。它是映射函数。
  2. :它取整数值;默认情况下,它是0。
  3. level(水平):如果轴是一个分层的MultiIndex,则按某一层次或多层次进行分组。
  4. as_index:它是布尔数据类型。对于聚合输出,我们返回带有分组标签的对象作为索引。它只与DataFrame输入有关。
  5. sort :对组键进行排序。我们通过关闭它来获得更好的性能。
  6. group_keys:它也是布尔数据类型,默认值为true。当调用apply时,将组键添加到索引中以识别碎片。
  7. Squeeze(挤压):它也是布尔数据类型,默认为False。如果可能的话,它可以减少返回类型的维度。否则,它返回一个一致的类型。

返回值

groupby()函数返回一个groupby对象,其中包含不同组的信息。

关于Pandas DataFrame groupby()的示例程序

写一个程序来展示Python中groupby()方法的工作:

import pandas as pd

dataset = {
    'Name': ['Rohit', 'Mohit', 'Sohit', 'Arun', 'Shubh'],
    'Roll no': ['01', '02', '03', '04', '05'],
    'Maths': ['93', '63', '74', '94', '83'],
    'Science': ['88', '55', '66', '94', '35'],
    'English': ['93', '74', '84', '92', '87']
}

df = pd.DataFrame(dataset)
group = df.groupby('Roll no')
print(group.first())

输出

Name Maths Science English
Roll no
01       Rohit    93      88      93
02       Mohit    63      55      74
03       Sohit    74      66      84
04        Arun    94      94      92
05       Shubh    83      35      87

在上面的例子中,我们可以看到有一个包含学生数据的数据集,我们根据卷号对这些数据进行分组。

请写一个程序,将数据按多列分组

import pandas as pd

dataset = {
    'Name': ['Rohit', 'Arun', 'Sohit', 'Arun', 'Shubh'],
    'Roll no': ['01', '02', '03', '04', '05'],
    'maths': ['93', '63', '74', '94', '83'],
    'science': ['88', '55', '66', '94', '35'],
    'english': ['93', '74', '84', '92', '87']}

df = pd.DataFrame(dataset)
group = df.groupby(['Name', 'Roll no'])
print(group.first())

输出

maths science english
Name  Roll no
Arun  02         63      55      74
      04         94      94      92
Rohit 01         93      88      93
Shubh 05         83      35      87
Sohit 03         74      66      84

在上面的例子中,我们可以看到我们已经完成了对多列的分组,即姓名和学号。 在这里我们可以看到,我们班上有两个阿伦,他们的卷号不同;因此,我们做了相应的分组。

在Jupyter笔记本上学习Pandas df.groupby()

AnacondaJupyter笔记本是从事机器学习和数据科学的重要工具之一。我们将从外部CSV数据中创建一个DataFrame,然后使用groupby方法根据不同的要求来获取数据。

你可以从这里下载外部文件。

现在,我们将使用以下两个数据集:

  1. ratings.csv
  2. cuisine.csv

所以,我们将从这些CSV数据中创建两个DataFrames。

让我们导入Pandas并使用Pandas read_csv()方法创建第一个DataFrame:

import pandas as pd

现在,创建评级_frame DataFrame:

ratings_frame = pd.read_csv('ratings.csv')
ratings_frame.head()

运行单元格,你将得到以下输出:

create two DataFrames in Pandas

下一步是创建一个 cuisine_frame DataFrame:

cuisine_frame = pd.read_csv('cuisine.csv')
cuisine_frame.head()

Create a DataFrame from Dictionary

从DataFrame的输出中,你可以看到两个DataFrame是通过placeID连接的。

如果你学过SQL,那么你可以记得主键外键的概念。

所以,收视率_frame中的外键placeID

现在,让我们来统计前五个地方ID的评分。

ratings_frame有我们需要的所有数据。因此,让我们使用groupby()函数来计算placeID的评分:

ratings_count = pd.DataFrame(ratings_frame.groupby('placeID')['rating'].count())
ratings_count.head()

fetch count using Pandas groupby

你调用**.groupby()**方法,并传递你想分组的列的名称,即 "**placeID"。**然后,你用["**rating"]**来定义你必须进行实际聚合的列。

你可以向.groupby()方法传递很多东西,而不仅仅是一个列名作为第一个参数。你也可以举出以下任何一个:

  1. 多个列名的列表
  2. dict或Pandas系列
  3. Numpy数组或Pandas索引,或这些的类似数组的可迭代项

你可以看到,我们已经获取了前五个placeID的评分计数。

类似的SQL查询会是这样的。

SELECT placeID, count(rating)
FROM df
GROUP BY placeID;

Pandas groupby vs. SQL groupby

大多数情况下,聚合能力被比作SQL中的GROUP BY子句。然而,SQL的GROUP BY和DataFrame的groupby()的操作方式是有区别的。

与SQL不同,Pandas groupby()方法没有序数位置引用的概念。因此,你将需要明确地通过Name来引用分组键。

Pandas数据框架在操作、重塑和混合数据的能力方面是通用的。DataFrame的一个突出特点是它能够聚合数据。

Pandas GroupBy对象方法

  1. 聚合方法将许多数据点 "粉碎"成一个关于这些数据点的聚合统计数字。例如,你可以取10个数字的总和平均数中位数,其中一个结果只是一个单一的数字。
  2. 过滤方法是用原始DataFrame的子集返回给你。这最常见的意思是使用.filter()方法,根据关于该组及其子表的一些临时统计资料,放弃整个组。在这个定义下,包括几个从每个组中排除特定行的方法也是有意义的。
  3. 转换方法返回的DataFrame的形状和索引与原始数据相同,但数值不同。通过聚合和过滤方法,结果的DataFrame通常会比输入的DataFrame的大小小。而转换方法则不然,它对单个数值本身进行转换,但保留了原始DataFrame的形状。
  4. 元方法不太关心你调用**.groupby()**的原始对象,而更注重于给你提供高层次的信息,如组的数量和这些组的索引。
  5. 绘图方法模仿了Pandas系列DataFrame的绘图API,但通常将输出分成多个子图。

总结

groupby是Pandas库中的一种方法,可以根据不同的变量集对数据进行分组。 最后,Pandas DataFrame groupby()的例子就结束了。