Python之数据拆分——groupby()方法


groupby()方法

groupby(
self,
by=None,
axis=0,
level=None,
as_index: bool = True,
sort: bool = True,
group_keys: bool = True,
squeeze: bool = False,
observed: bool = False,
)

部分参数表示的含义如下:

  1. by:用于确定进行分组的依据
  2. axis:表示分组轴的方向,可以为0或1,默认为0
  3. level:如果某个轴是一个MultiIndex对象(索引层次结构),则会按特定级别或多个级别分组
  4. as_index:表示聚合后的数据是否以组标签作为索引的DataFrame对象输出,接受布尔值,默认为True
  5. sort:表示是否对分组标签进行排序,接受布尔值,默认为True

通过groupby()方法执行分组操作,会返回一个GroupBy对象,该对象实际上并没有进行任何计算,只是包含一些而关于分组键的中间数据而已。

一般,使用Series调用groupby()方法返回的是SeriesGroupBy对象,而使用DataFrame调用groupby()方法返回的是DataFrameBy对象。



在进行分组时,通过指定by参数来确定分组标准,常用的分组方式主要有四种:

  • 列表或数组,其长度必须与待分组的轴一样
  • DataFrame对象中某列的名称
  • 字典或Series对象,给出待分组轴上的值与分组名称之间的对应关系
  • 函数,用于处理轴索引或索引中的各个标签

通过列名进行分组

代码:

import numpy as np
import pandas as pd


df = pd.DataFrame({
    
    "key": ['C', 'B', 'C', 'A', 'B', 'B', 'A', 'C', 'A'],
                   "Data": [2, 4, 6, 8, 10, 1, 14, 16, 18]})
print(df)
group_obj = df.groupby(by='key')
print("df.groupby(by='key'):\n", group_obj)

输出结果:

  key  Data
0   C     2
1   B     4
2   C     6
3   A     8
4   B    10
5   B     1
6   A    14
7   C    16
8   A    18
df.groupby(by='key'):
 <pandas.core.groupby.generic.DataFrameGroupBy object at 0x000002018919F2B0>

从输出结果可以看出,DataFrame经过分组之后得到了一个DataFrameGroupBy对象,该对象是一个可迭代的对象,即只有在真正需要的时候才会执行计算(惰性计算)

如果要查看每个分组的具体内容,应该使用for循环遍历DataFrameGroupBy对象。

代码:

for i in group_obj:
    print(i)

输出结果:

('A',   key  Data
3   A     8
6   A    14
8   A    18)
('B',   key  Data
1   B     4
4   B    10
5   B     1)
('C',   key  Data
0   C     2
2   C     6
7   C    16)

通过Series对象进行分组

Series对象与原数据的行索引长度相等

将Series对象传给by参数,作为分组键拆分DataFrame对象

代码:

df1 = pd.DataFrame({
    
    'key1': ['A', 'A', 'B', 'B', 'A'],
                    'kye2': ['one', 'two', 'one', 'two', 'one'],
                    'data1': [2, 3, 4, 6, 8],
                    'data2': [3, 5, 6, 3, 7]})
print(df1)

se = pd.Series(['a', 'b', 'c', 'a', 'b'])
group_obj1 = df1.groupby(by=se)
for i in group_obj1:
    print(i)

输出结果:

key1 kye2  data1  data2
0    A  one      2      3
1    A  two      3      5
2    B  one      4      6
3    B  two      6      3
4    A  one      8      7

('a',   key1 kye2  data1  data2
0    A  one      2      3
3    B  two      6      3)
('b',   key1 kye2  data1  data2
1    A  two      3      5
4    A  one      8      7)
('c',   key1 kye2  data1  data2
2    B  one      4      6)

从输出结果可以看出,se将df1对象分成a,b,c三组,其中索引0和3对应的两行为a组数据,索引1和4对应的两行为b组数据,索引2对应的一行为c组数据。


Series对象与原数据的行索引长度不等

代码:

se1 = pd.Series(['a', 'b', 'a'])
group_obj2 = df1.groupby(se1)
for i in group_obj2:
    print("group_obj2:\n", i)

输出结果:

('a',   key1 kye2  data1  data2
0    A  one      2      3
2    B  one      4      6)
('b',   key1 kye2  data1  data2
1    A  two      3      5)

由于se1只有三行数据,所以它只需要对df对象的前三行数据进行分组,即第一行第三行分为一组,最后一行分为一组,而不会将全部的数据进行分组


通过字典进行分组

用字典对DataFrame进行分组时,需要确定轴的方向及字典中的映射关系,即字典中的键为列名,字典的值为自定义的分组名。


按照columns轴的方向进行分组

代码:

df2 = DataFrame({
    
    'a': [1, 2, 4, 8, 3],
                 'b': [9, 6, 3, 7, 5],
                 'c': [2, 3, 4, 6, 8],
                 'd': [3, 5, 6, 3, 7]})
mapping = {
    
    'a': '第一组', 'b': '第二组', 'c': '第三组', 'd': '第一组'}
print(df2)
by_columns = df2.groupby(by=mapping, axis=1)
print("by_columns:")
for i in by_columns:
    print(i)

输出结果:

   a  b  c  d
0  1  9  2  3
1  2  6  3  5
2  4  3  4  6
3  8  7  6  3
4  3  5  8  7
by_columns:
('第一组',    a  d
0  1  3
1  2  5
2  4  6
3  8  3
4  3  7)
('第三组',    c
0  2
1  3
2  4
3  6
4  8)
('第二组',    b
0  9
1  6
2  3
3  7
4  5)

拆分df2时,将a列、d列数据映射到第一组;将b列映射到第二组,将d列数据映射到第三组。


按照index轴的方向进行分组

代码

mapping1 = {
    
    0: '第一组', 1: '第二组', 2: '第三组', 3: '第二组', 4: '第一组'}
by_index = df2.groupby(mapping1, axis=0)
print("by_index:")
for i in by_index:
    print(i)

输出结果:

by_index:
('第一组',    a  b  c  d
0  1  9  2  3
4  3  5  8  7)
('第三组',    a  b  c  d
2  4  3  4  6)
('第二组',    a  b  c  d
1  2  6  3  5
3  8  7  6  3)

拆分df2时,将0行、4行数据映射到第一组;将1行、3行映射到第二组,将2行数据映射到第三组。


通过函数进行分组

使用函数作为分组键会更加灵活,任何一个被当作分组键的函数都会在各个索引值上被调用一次,返回的值会被用作分组名称。

代码:

df2 = DataFrame({
    
    'a': [1, 2, 4, 8, 3],
                 'b': [9, 6, 3, 7, 5],
                 'c': [2, 3, 4, 6, 8],
                 'd': [3, 5, 6, 3, 7]},
                index=['Bob', 'Alice', 'Job', 'Jack', 'Helen'])
group_obj3 = df2.groupby(by=len)
print("group_obj3")
for i in group_obj3:
    print(i)

输出结果:

group_obj3
(3,      a  b  c  d
Bob  1  9  2  3
Job  4  3  4  6)
(4,       a  b  c  d
Jack  8  7  6  3)
(5,        a  b  c  d
Alice  2  6  3  5
Helen  3  5  8  7)

在调用groupby()方法时传入了内置函数len(),表明len()函数会对行索引一列执行求长度的操作,以行索引名称的长度进行分组,则长度相同的行索引名称会分成一组。

猜你喜欢

转载自blog.csdn.net/Jormungand_V/article/details/109999605
今日推荐