Python数据分析之数据聚合与分组运算(拆分、应用、合并)

1.分组与聚合的原理

在Pandas中:

分组:指使用特定的条件将原数据划分为多个组;

聚合:对每个分组中的数据执行某些操作,最后将计算的结果进行整合。

1.2分组与聚合的过程分为三步

1.2.1拆分

将数据集按照些标准拆分为若干个组。split拆分方法

1.2.2应用

将某个函数或方法(内置和自定义均可)应用到每个分组。apply方法应用

1.2.3合并

将产生的新值整合到结果对象中。combine方法整合

2. 通过groupby()方法将数据拆分成组

​ 在Pandas中,可以通过groupby()方法将数据集按照某些标准划分成若干个组。

2.1 groupby()方法

by:用于确定进行分组的依据。

level:两层索引指定内外层,0/1。

axis:表示分组轴的方向。

sort:表示是否对分组标签进行排序,接收布尔值,默认为True。

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

•使用Series调用groupby()方法返回的是SeriesGroupBy对象。

•使用DataFrame调用groupby()方法返回的是DataFrameBy对象。

2.2 groupby()方法的by参数

​ by 参数可以接受的数据有4种:列表或数组、DataFrame某列、字典或Series对象、函数

2.2.1 按列名进行分组

​ 如果DataFrame对象的某一列数据符合划分成组的标准,则可以将该列当做分组键来拆分数据集。

df = pd.DataFrame({"Key":['C','B','C','A','B','B','A','C','A'],
                   "Data":[2,4,6,8,10,1,14,16,18]})
                   
# 通过groupby()方法将数据集按照某些标准划分成若干个组。
# 按Key列进行分组 或 通过列名进行分组
# 如果DataFrame对象的某一列数据符合划分成组的标准,则可以将该列当做分组键来拆分数据集。

df.groupby(by='Key')

查看每个分组的具体内容,使用for循环遍历DataFrameGroupBy对象

group_obj = df.groupby('Key')
# 遍历分组对象
for i in group_obj:
    print(i)

2.2.2 按Series对象进行分组

​ 将自定义的Series类对象作为分组键进行分组。

# 按自定义Series对象进行分组 或 通过Series对象进行分组
# 将自定义的Series类对象作为分组键进行分组。
df = pd.DataFrame({'key1': ['A', 'A', 'B', 'B', 'A'],
                   'key2': ['one', 'two', 'one', 'two', 'one'],
                   'data1': [2, 3, 4, 6, 8],
                   'data2': [3, 5, 6, 3, 7]})
se = pd.Series(['a', 'b', 'c', 'a', 'b'])
group_obj = df.groupby(by = se)   
for i in group_obj:                  # 遍历分组对象
    print(i)

​ 如果Series对象与Pandas对象的索引长度不相同时,则只会将具有相同索引的部分数据进行分组。

# 当Series长度与原数据的索引值长度不同时
se = pd.Series(['a', 'a', 'b'])
group_obj = df.groupby(se)
for i in group_obj:           # 遍历分组对象
    print(i)

2.2.3 按字典进行分组

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

# 按字典分组 或 通过字典进行分组
num_df = pd.DataFrame({'a': [1, 2, 3, 4, 5],
                    'b': [6, 7, 8, 9, 10],
                    'c': [11, 12, 13, 14, 15],
                    'd': [5, 4, 3, 2, 1],
                    'e': [10, 9, 8, 7, 6]})
# 定义字典确定分组关系
mapping = {'a':'第一组','b':'第二组','c':'第一组',
           'd':'第三组','e':'第二组'}

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

by_column = num_df.groupby(mapping, axis=1)

for i in by_column:
    print(i)

2.2.4 按函数进行分组

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

# 使用内置函数len进行分组  或 通过函数进行分组
df = pd.DataFrame({'a': [1, 2, 3, 4, 5],
                   'b': [6, 7, 8, 9, 10],
                   'c': [5, 4, 3, 2, 1]},
                  index=['Sun', 'Jack', 'Alice', 'Helen', 'Job'])
# 将函数作为分组键会更加灵活,任何一个被当做分组键的函数都会在各个索引值上被调用一次,返回的值会被用作分组名称。
groupby_obj = df.groupby(len)    
for group in groupby_obj:        # 遍历分组对象
    print(group)

3.数据聚合

import pandas as pd
import numpy as np
df = pd.DataFrame({'key1': ['A', 'A', 'B', 'B', 'A'],
                   'key2': ['one', 'two', 'one', 'two', 'one'],
                   "data1": [2, 3, 4, 6, 8],
                   "data2": [3, 5, np.nan, 3,7]})
df.groupby('key1') # 按key1进行分组 
# 打印分组对象
for i in df.groupby('key1'): 
    print(i)

3.1使用内置统计方法聚合数据

​ Pandas中内置的统计方法,比如用于获取最大值和最小值的max()和mix(),这些方法常用于简单地聚合分组中的数据。

# 求平均数
# 按key1进行分组,求每个分组的平均值
df.groupby('key1').mean()

3.2面向列的聚合方法

​ 如果内置方法无法满足聚合要求时,则可以自定义函数,将它作为参数传给agg()方法,实现Pandas对象的聚合运算。

data_frame = pd.DataFrame(np.arange(36).reshape((6,6)),
                       columns=list('abcdef'))
# 增加一列
data_frame['key'] = pd.Series(list('aaabbb'), name='key')
data_frame

3.2.1 agg()方法

func:表示用于汇总数据的函数,可以为单个函数或函数列表。

axis:表示函数作用于轴的方向,0或index表示将函数应用到每一列;1或columns表示将函数应用到每一行,该参数的默认值为0。

3.2.2 对每一列数据应用同一个函数

​ 通过agg()方法进行聚合,最简单的方式就是给该方法的func参数传入一个函数,这个函数既可以是内置的,也可以自定义的。

def range_data_group(arr):
      return arr.max()-arr.min()
# 使用自定义函数聚合分组数据
data_group.agg(range_data_group)  

# 按key列进行分组
data_group = data_frame.groupby('key')
# 利用列表推导式查看分组数据信息
list1=[x for x in data_group]
list1
# 查看分组数据信息二
for x in data_group:
    print(x)
# 把分组后列表数据转换为字典类型
# 输出a组数据信息
dict(list1)['a']
# 输出b组数据信息
dict(list1)['b']
#如果内置方法无法满足聚合要求时,则可以自定义函数,将它作为参数传给agg()方法,实现Pandas对象的聚合运算。
# 对每一列数据应用同一个函数,例如求每个分组的和
data_group.agg(sum)
data_group.agg(range_data_group)  # 使用自定义函数聚合分组数据

3.2.3 对某列数据应用不同的函数

​ 可以将两个函数的名称放在列表中,之后在调用agg()方法进行聚合时作为参数传入即可.

# 对一列数据用两种函数聚合
data_group.agg([range_data_group, sum])
# 为了能更好地反映出每列数据的信息,
# 可以使用“(name,function)”元组将function(函数名)替换为name(自定义名称)。
data_group.agg([("极差", range_data_group), ("和", sum)])

3.2.4 对不同列数据应用不同函数

​ 如果希望对不同的列使用不同的函数,则可以在agg()方法中传入一个{“列名”:“函数名”}格式的字典。

data_frame = pd.DataFrame(np.arange(36).reshape((6,6)),
                       columns=list('abcdef'))
data_group = data_frame.groupby('key')
data_group
data_group.agg({'a': 'sum', 'b': 'mean', 'c': range_data_group})
agg()方法执行聚合操作时,会将一组标量值参与某些运算后转换为一个标量值。

4.分组级运算

4.1 数据转换

4.1.1 transfrom()方法

​ 如果希望保持与原数据集形状相同,那么可以通过transfrom()方法实现。

  • 上述方法中只有一个func参数,表示操作Pandas对象的函数。
  • transfrom()方法会把func函数应用到各个分组中,并且将计算结果放在适当的位置上。
  •   transform()方法返回的结果有两种,一种是可以广播的标量值(np.mean),另一种可以是与分组大小相同的结果数组。
    
df= pd.DataFrame({'A': range(3),'B': range(1,4)})
df
df.transform(lambda x: x+ 1)

4.2 数据应用

4.2.1 apply()方法

​ apply()方法的使用是十分灵活的,它可以在许多标准用例中替代聚合和转换,另外还可以处理一些比较特殊的用例。

func:表示应用于某一行或某一列的函数。

axis:表示函数操作的轴向。

broadcast:表示是否将数据进行广播。

data_frame = pd.DataFrame(np.arange(36).reshape((6,6)),
                       columns=list('abcdef'))
data_frame['f']
def apply_f(x,bais):
    return x+bais
#以元组方式传入额外参数
data_frame['f']=data_frame['f'].apply(apply_f,args=(-3,))
data_frame['f']
  • 3
    点赞
  • 40
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
Python 中,可以使用 pandas 库来合并数据框。数据合并通常包括两个方面:连接和聚合。 连接指的是将两个数据框按照某些列进行合并,有以下几种方式: 1. 内连接(inner join):只保留两个数据框中都存在的行。 2. 左连接(left join):将左边的数据框所有行都保留,将右边的数据框中匹配到的行合并到左边的数据框中。 3. 右连接(right join):将右边的数据框所有行都保留,将左边的数据框中匹配到的行合并到右边的数据框中。 4. 外连接(outer join):将两个数据框所有的行都保留,空值用 NaN 填充。 聚合指的是根据某些列对数据框进行分组,并计算每组的统计量,如均值、中位数等。可以使用 pandas 中的 groupby 方法来实现。 下面是一个示例代码,展示了如何进行数据合并聚合: ```python import pandas as pd # 创建两个数据框 df1 和 df2 df1 = pd.DataFrame({'key': ['A', 'B', 'C', 'D'], 'value': [1, 2, 3, 4]}) df2 = pd.DataFrame({'key': ['B', 'D', 'E', 'F'], 'value': [5, 6, 7, 8]}) # 内连接 inner_join = pd.merge(df1, df2, on='key', how='inner') print('内连接:\n', inner_join) # 左连接 left_join = pd.merge(df1, df2, on='key', how='left') print('左连接:\n', left_join) # 右连接 right_join = pd.merge(df1, df2, on='key', how='right') print('右连接:\n', right_join) # 外连接 outer_join = pd.merge(df1, df2, on='key', how='outer') print('外连接:\n', outer_join) # 根据 key 列进行分组,并计算每组的均值和中位数 grouped = outer_join.groupby('key').agg({'value': ['mean', 'median']}) print('分组聚合:\n', grouped) ``` 输出结果如下: ``` 内连接: key value_x value_y 0 B 2 5 1 D 4 6 左连接: key value_x value_y 0 A 1 NaN 1 B 2 5.0 2 C 3 NaN 3 D 4 6.0 右连接: key value_x value_y 0 B 2.0 5 1 D 4.0 6 2 E NaN 7 3 F NaN 8 外连接: key value_x value_y 0 A 1.0 NaN 1 B 2.0 5.0 2 C 3.0 NaN 3 D 4.0 6.0 4 E NaN 7.0 5 F NaN 8.0 分组聚合: value mean median key A 1.0 1.0 B 3.5 3.5 C 3.0 3.0 D 5.0 5.0 E 7.0 7.0 F 8.0 8.0 ```

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

liangpi_hero

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值