DC's blog DC's blog
首页
  • 计算机基础
  • linux基础
  • mysql
  • git
  • 数据结构与算法
  • axure
  • english
  • docker
  • opp
  • oop
  • 网络并发编程
  • 不基础的py基础
  • 设计模式
  • html
  • css
  • javascript
  • jquery
  • UI
  • 第一次学vue
  • 第二次学vue
  • Django
  • drf
  • drf_re
  • 温故知新
  • flask
  • 前后端不分离

    • BBS
    • 订单系统
    • CRM
  • 前后端部分分离

    • pear-admin-flask
    • pear-admin-django
  • 前后端分离

    • 供应链系统
  • 理论基础
  • py数据分析包
  • 机器学习
  • 深度学习
  • 华中科大的网课
  • cursor
  • deepseek
  • 杂文
  • 罗老师语录
  • 关于我

    • me
  • 分类
  • 归档
GitHub (opens new window)

DC

愿我一生欢喜,不为世俗所及.
首页
  • 计算机基础
  • linux基础
  • mysql
  • git
  • 数据结构与算法
  • axure
  • english
  • docker
  • opp
  • oop
  • 网络并发编程
  • 不基础的py基础
  • 设计模式
  • html
  • css
  • javascript
  • jquery
  • UI
  • 第一次学vue
  • 第二次学vue
  • Django
  • drf
  • drf_re
  • 温故知新
  • flask
  • 前后端不分离

    • BBS
    • 订单系统
    • CRM
  • 前后端部分分离

    • pear-admin-flask
    • pear-admin-django
  • 前后端分离

    • 供应链系统
  • 理论基础
  • py数据分析包
  • 机器学习
  • 深度学习
  • 华中科大的网课
  • cursor
  • deepseek
  • 杂文
  • 罗老师语录
  • 关于我

    • me
  • 分类
  • 归档
GitHub (opens new window)
  • 理论基础

  • Py数据分析包

    • numpy
    • pandas基本操作
    • pandas数据清洗
    • pandas数据集成
    • pandas高级操作
      • 数据转换
        • 数据替换
        • 索引替换
        • 值替换
        • 数据映射
        • 数据运算
        • ★★★ map函数
        • apply函数
        • applymap函数
        • transform函数
        • 案例应用
        • 报销处理
        • 身份ID处理
        • 数据映射
      • 数学和统计方法
      • 数据排序
      • 分箱操作
        • 等距分箱
        • 等频分箱
        • 应用场景
      • 随机抽样
      • ★ 数据分组
        • 分组+聚合
        • 分组+transform/apply
        • 分组+agg
      • ★数据透视
      • 项目案例
    • pandas时间序列
    • pandas样式制定
    • pandas绘图
    • 商场销售数据分析
    • 美妆数据分析
    • 连锁超市数据分析
    • 财务经营分析
    • 拍拍贷数据分析
    • ★一切从简
    • 一些杂乱的思考
  • 机器学习

  • 深度学习

  • 华中科大的网课

  • AI
  • Py数据分析包
DC
2024-08-13
目录

pandas高级操作

该篇博客我们来康康pandas的高级操作!!

asdcf


# 数据转换

# 数据替换

测试数据准备

>>> import numpy as np
>>> import pandas as pd
>>> df = pd.DataFrame(
             data=np.random.randint(0,10,size=(5,3)),
             index=list('ABCDE'),
             columns=["Python","Tensorflow","Keras"])
>>> df.iloc[4,2] = None
1
2
3
4
5
6
7
# 索引替换

■ 重命名轴索引

>>> df
   Python  Tensorflow  Keras
A       8           4    0.0
B       0           0    3.0
C       6           8    1.0
D       8           3    0.0
E       3           8    NaN
>>> # 需求: 将行索引"A"替换成"AA", "B"替换成"BB" ; 将列索引 "Python"替换成"人工智能".
>>> df.rename(index={"A":"AA","B":"BB"},columns={"Python":"人工智能"})  # 返回新对象,并未修改原df对象
    人工智能  Tensorflow  Keras
AA     8           4    0.0
BB     0           0    3.0
C      6           8    1.0
D      8           3    0.0
E      3           8    NaN
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15

■ 匿名函数批量重命名

# -- 匿名函数应用索引替换
# 原始数据的列索引不符合Python的命名规范,给其进行重命名(例如: Row ID改为Row_ID,Sub-Category改为Sub_Category)
df = pd.read_csv('superstore_dataset2011-2015.csv')
df.rename(columns=lambda x:x.replace(' ','_').replace('-','_'))
1
2
3
4
# 值替换

■ 全局的单值替换

>>> df
   Python  Tensorflow  Keras
A       8           4    0.0
B       0           0    3.0
C       6           8    1.0
D       8           3    0.0
E       3           8    NaN
>>> df.replace(to_replace=8,value="eight")
  Python Tensorflow  Keras
A  eight          4    0.0
B      0          0    3.0
C      6      eight    1.0
D  eight          3    0.0
E      3      eight    NaN
1
2
3
4
5
6
7
8
9
10
11
12
13
14

■ 全局的多值替换

>>> df
   Python  Tensorflow  Keras
A       8           4    0.0
B       0           0    3.0
C       6           8    1.0
D       8           3    0.0
E       3           8    NaN
>>> # 多个值替换成同一个值
>>> df.replace(to_replace=[0,8],value=9999)
   Python  Tensorflow   Keras
A    9999           4  9999.0
B    9999        9999     3.0
C       6        9999     1.0
D    9999           3  9999.0
E       3        9999     NaN
>>> # 多个值替换成不同的值
>>> df.replace(to_replace={0:"zero",8:"eight",np.nan:"空值"})
  Python Tensorflow Keras
A  eight          4  zero
B   zero       zero   3.0
C      6      eight   1.0
D  eight          3  zero
E      3      eight    空值
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23

■ 指定列中的元素进行替换

>>> df
   Python  Tensorflow  Keras
A       8           4    0.0
B       0           0    3.0
C       6           8    1.0
D       8           3    0.0
E       3           8    NaN
>>> # 将Python这一列中等于6的,替换为"six"
>>> df.replace(to_replace={"Python":6},value="six")
  Python  Tensorflow  Keras
A      8           4    0.0
B      0           0    3.0
C    six           8    1.0
D      8           3    0.0
E      3           8    NaN
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15

# 数据映射

★ 只能针对一组数据/serise对象/某一行或某一列

通过map函数对DataFrame表格中的某一列或某一行所对应的这一组数据当中的每一个元素都绑定一个固定形式的标签(eg:字符串).

>>> import numpy as np
>>> import pandas as pd
>>> dic_data = {
        'name':['zhangsan','lisi','wangwu','lisi'],
        'salary':[10000,12000,8000,12000]
    }
>>> df = pd.DataFrame(data=dic_data)
>>> df
       name  salary
0  zhangsan   10000
1      lisi   12000
2    wangwu    8000
3      lisi   12000
>>> # 字典充当关系映射表
>>> dic = {'zhangsan':"张三",'lisi':'李四'}
>>> # 根据关系映射表将'zhangsan'绑定成'张三','lise'绑定成'李四'. 最后将map的结果作为原始数据新的一列!!
>>> df['e_name'] = df['name'].map(dic)
>>> df
       name  salary e_name
0  zhangsan   10000    张三
1      lisi   12000    李四
2    wangwu    8000    NaN  # 注:关系映射表中没有wangwu的映射,就用NaN值进行了填充!
3      lisi   12000    李四
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23

# 数据运算

# ★★★ map函数

map函数对Series数据的运算处理(map作为Series对象的运算工具)

>>> dic_data = {
        'name':['zhangsan','lisi','wangwu','lisi'],
        'salary':[10000,12000,8000,12000]
    }
>>> df = pd.DataFrame(data=dic_data)
>>> df
       name  salary
0  zhangsan   10000
1      lisi   12000
2    wangwu    8000
3      lisi   12000
>>> # map不仅可以映射,还可以作运算工具. 给df['salary']这一组数据的每一个元素作运算!示例中是算稅后薪资.
>>> def after_sal(s):
        return s-(s-3000)*0.5
>>> df['after_sal'] = df['salary'].map(after_sal)
>>> df
       name  salary  after_sal
0  zhangsan   10000     6500.0
1      lisi   12000     7500.0
2    wangwu    8000     5500.0
3      lisi   12000     7500.0
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
# apply函数

apply也可以像map一样充当运算工具, 不过apply运算效率要远远高于map. 因此在数据量级较大的时候可以使用apply.

★ apply函数可以对Series或DataFrame进行运算处理

测试数据准备

import numpy as np
import pandas as pd

df = pd.DataFrame(data=np.random.randint(0, 10, size=(6, 3)),
                  index=list('ABCDEF'),
                  columns=['Python', 'Tensorflow', 'Keras'])
df.iloc[4, 2] = None
1
2
3
4
5
6
7

■ apply可作用在Series中/可以对Series中的每一个元素进行运算处理

df['Keras_res1'] = df['Keras'].apply(lambda x: True if x > 3 else False)
df['Keras_res2'] = df['Keras'] > 3
print(df)

"""
   Python  Tensorflow  Keras  Keras_res1  Keras_res2
A       4           6    1.0       False       False
B       3           9    1.0       False       False
C       2           2    4.0        True        True
D       5           4    8.0        True        True
E       0           5    NaN       False       False
F       1           0    7.0        True        True
"""
1
2
3
4
5
6
7
8
9
10
11
12
13

■ apply作用在DataFrame中:可以对df中的行或列进行运算处理

def convert(x):  # 自定义方法
    return x.mean(), x.count()

df["apply_res"] = df.apply(convert, axis=1)
print(df)

"""
   Python  Tensorflow  Keras                apply_res
A       4           4    3.0  (3.6666666666666665, 3)
B       6           7    4.0   (5.666666666666667, 3)
C       8           6    2.0   (5.333333333333333, 3)
D       5           8    9.0   (7.333333333333333, 3)
E       9           0    NaN                 (4.5, 2)
F       9           8    3.0   (6.666666666666667, 3)
"""
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
# applymap函数

★applymap函数, DataFrame专有, 对df中每一个元素进行运算处理

import numpy as np
import pandas as pd

df = pd.DataFrame(data=np.random.randint(0, 10, size=(4, 3)),
                  index=list('ABCD'),
                  columns=['Python', 'Tensorflow', 'Keras'])
df.iloc[2, 2] = None

print(df)
res1 = df.applymap(lambda x: x + 100)
print(res1)
res2 = df + 100
print(res2)

"""
   Python  Tensorflow  Keras
A       8           5    0.0
B       4           2    1.0
C       6           1    NaN
D       8           4    6.0
   Python  Tensorflow  Keras
A     108         105  100.0
B     104         102  101.0
C     106         101    NaN
D     108         104  106.0
   Python  Tensorflow  Keras
A     108         105  100.0
B     104         102  101.0
C     106         101    NaN
D     108         104  106.0
"""
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
# transform函数
import numpy as np
import pandas as pd

df = pd.DataFrame(data = np.random.randint(0,10,size = (10,3)),
                  index = list('ABCDEFHIJK'),
                  columns=['Python','Tensorflow','Keras'])

# ■ 功能1: 对Series/一组数据的每个元素作多种运算,执行多项计算
# 注!!只能传入对单个元素可作的运算(非聚合运算),聚合不行(eg:np.main就不行)
df['Python'].transform([np.sqrt,np.exp]) # Series处理

# ■ 功能2:对数据表格的多列作不同形式的运算
def convert(x):
    if x.mean() > 5:
        x *= 10
    else:
        x *= -10
    return x
df.transform({'Python':convert,'Tensorflow':lambda x:np.min(x),'Keras':lambda x:np.max(x)}) # DataFrame处理
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19

# 案例应用

在pycharm中打印pandas读取的excel表格数据,为了显示的工整完整,会进行以下配置:
  
pd.set_option('display.unicode.east_asian_width', True)  # 使得 Pandas 在计算列宽时考虑东亚字符的实际宽度
pd.set_option("display.width", None)                     # 自动调整显示宽度,消除打印不完全中间的省略号
pd.set_option("display.max_columns", None)               # 显示所有列
pd.set_option("display.max_rows", None)                  # 显示所有行
pd.set_option('display.max_colwidth', None)              # 显示列宽度
1
2
3
4
5
6
7
# 报销处理

image-20240816115519262

测试代码如下:

★ df['邮箱'].str 变成StringMethods类型,就可使用str、findall等方法!!

import pandas as pd

df = pd.read_excel('报销处理-Python版.xlsx').head()
print(df)
# 需求1: 将部门列的数据和姓名列的数据合并到一起显示在部门-姓名列中  --  列拼接(字符串拼接)
# ps: 若部门和姓名里有空值,那么就先做数据清洗,得保证这两列都是字符串,因为要做加法的字符串拼接!
df['部门-姓名'] = df['姓名'] + '-' + df['部门']

# 需求2: 将邮箱列中的用户名和密码提取出来填充到用户名列和密码列中  -- 列切分(字符串切分)
userNameList = []
pwdList = []

def func(x):
    user_name = x[0]
    pwd = x[1]
    userNameList.append(user_name)
    pwdList.append(pwd)

df['邮箱'].str.split('-').map(func)  # df['邮箱'].str 变成StringMethods类型,就可使用str、findall等方法!!
df['用户名'] = userNameList
df['密码'] = pwdList


# 需求3: 提取费用明细列中的数字,相加到合计列中  --  取字符串中的数据作加法.
def func_sum(alist):
    # 取出来的数字可能是字符串类型,所以相加时,做个类型转换会更保险!!
    return pd.Series(data=alist).astype('int').sum()

df['合计'] = df['费用明细'].str.findall('\d+').map(func_sum)  # 取出列表中的数字作加法.

print()
print(df)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
# 身份ID处理

image-20240816121617382

测试代码如下:

import pandas as pd

df = pd.read_excel('身份ID处理-Python版.xlsx').head()
print(df)

# 需求1: 身份证号是数字类型,将其转换成字符串类型,并进行脱敏处理
df['身份ID(脱敏出生年月)'] = df['身份ID'].astype('str').map(lambda x: x.replace(x[6:14], '*' * 8))

# 需求2: 性别填充
df['性别'] = df['身份ID'].astype('str').map(lambda x: "女" if int(x[-2]) % 2 == 0 else "男")

print()
print(df)
1
2
3
4
5
6
7
8
9
10
11
12
13
# 数据映射

image-20240816123549691

测试代码如下: (该示例是map作映射的典型案例.)

import numpy as np
import pandas as pd

df_data = pd.read_excel('数据映射-Python版.xlsx', sheet_name='源数据').head()
df_price = pd.read_excel('数据映射-Python版.xlsx', sheet_name='进价单').head()
print(df_data)
print(df_price)

dic = {}
for index in df_price.index:
    row = df_price.iloc[index]  # 降维取第n行,取到series对象
    dic[row[0]] = row[1]
print(dic)

df_data['进价'] = df_data['小类'].map(dic)  # map作映射
df_data['税前成交额'] = df_data['出货量'] * df_data['进价']
df_data['税后收入'] = df_data['税前成交额'].map(lambda x: x - (x - 15000) * 0.23)

print()
print(df_data)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20

# 数学和统计方法

准备测试数据

import numpy as np
import pandas as pd

df = pd.DataFrame(data=np.random.randint(0, 100, size=(6, 3)),
                  index=list('ABCDEF'),
                  columns=['Python', 'Tensorflow', 'Keras'])
df.iloc[0, 1] = None
df.iloc[2, 2] = None
print(df)

"""
   Python  Tensorflow  Keras
A       7         NaN   74.0
B      43        59.0   52.0
C      34        18.0    NaN
D      41        42.0   87.0
E      89        72.0   14.0
F      75        34.0   28.0
"""
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19

image-20240816143358792

常用方法如下:

方法 作用 参数 结果
df.count() 沿着 某轴 求非NaN值的数量 axis 默认为0 Serise对象
df.max() 沿着 某轴 求最大值 axis 默认为0 Serise对象
df.min() 沿着 某轴 求最小值 axis 默认为0 Serise对象
df.median() 沿着 某轴 求中位数 axis 默认为0 Serise对象
df.sum() 沿着 某轴 求和 axis 默认为0 Serise对象
df.mean() 沿着 某轴 求平均值 axis 默认为0 Serise对象
df.cumsum() 沿着 某轴 作累加 axis 默认为0 DataFrame对象
df.cumprod() 沿着 某轴 作累乘 axis 默认为0 DataFrame对象
df.std() 沿着 某轴 求标准差 axis 默认为0 Serise对象
df.var() 沿着 某轴 求方差 axis 默认为0 Serise对象
df.quantile(q = [0.2,0.4,0.8]) 沿着 某轴 求分位数 axis 默认为0 DataFrame对象
df.describe() 查看数值型列的汇总统计计数
平均值、标准差、最小值、四分位数、最大值
无axis参数! DataFrame对象
df.pct_change() 将每个元素与其前一个元素进行比较
并计算前后数值的百分比变化
axis 默认为0 DataFrame对象
df.idxmax() 沿着 某轴 求最大值的索引标签 axis 默认为0 Serise对象
df.idxmin() 沿着 某轴 求最小值的索引标签 axis 默认为0 Serise对象
df['Python'].rank() 对序列中的元素值排名 Serise对象
df['Python'].argmin() 计算最小值位置 一个数
df['Python'].argmax() 计算最大值位置 一个数

ps: df['Python'].rank()对序列中的元素值排名,该函数的返回值的也是一个序列,包含了原序列中每个元素值的名次.
如果序列中包含两个相同的的元素值,那么会为其分配两者的平均排名.


# 数据排序

测试截图如下:

image-20240816145506624

测试代码如下:

import numpy as np
import pandas as pd

df = pd.DataFrame(data=np.random.randint(0, 30, size=(6, 3)),
                  index=list('qwerty'),
                  columns=['Python', 'Keras', 'Pytorch'])
print(df)

# 1、索引列名排序
res = df.sort_index(axis=0, ascending=True)  # 按索引排序,降序
print(res)
res = df.sort_index(axis=1, ascending=False)  # 按列名排序,升序
print(res)

# 2、属性值排序
res = df.sort_values(by=['Python'])  # 根据Python这一列的值进行排序
print(res)
res = df.sort_values(by=['Python', 'Keras'])  # 先按Python,再按Keras排序
print(res)

# 3、返回属性n大或者n小的值
res = df.nlargest(3, columns='Keras')  # 根据属性Keras排序,返回最大10个数据
print(res)
df.nsmallest(5, columns='Python')  # 根据属性Python排序,返回最小5个数据
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24

# 分箱操作

在数据分析和机器学习、数据挖掘中都会广泛的使用, 在后续的学习中, 学习了特征工程后就明白了.

数据分箱 (也称为离散分箱或分段) 是一种数据预处理技术. 
用于减少次要观察误差的影响, 是一种将多个连续值分组为较少数量的"分箱"的方法.
说白了就是将连续型特征进行离散化!!!
1
2
3

★ 关键词: 多个 [连续值] 分组, 这些连续值放入较小数量的箱子 (*≧ω≦) 等距比等频用的多.

# 等距分箱

image-20240816153456677

ret.value_counts() 查看每个箱子有多少个元素.

截图中的示例代码如下:

import pandas as pd
import numpy as np

age = np.arange(1, 31, step=1)  # 连续性特征
print(age)

# bins表示分箱的箱子个数(分组数量); labels可以给每一个箱子起一个名字
ret = pd.cut(age, bins=4, labels=['A', 'B', 'C', 'D']) 
print(ret)
print(type(ret))
print(ret.value_counts())
# age = ret  # 将分箱后的结果重新赋值给age,则age就被离散化

# 可以给bins赋值一个列表,表示n个箱子的间距,就可以实现手动指定箱子的间距
age = np.arange(1, 31, step=1)
ret = pd.cut(age, bins=[1, 10, 20, 25, 30])
print(ret.value_counts())
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17

# 等频分箱

import pandas as pd
import numpy as np

x = np.random.random(size=(100,))
ret = pd.qcut(x, 4)
print(ret.value_counts())

ret = pd.qcut(x, 4, labels=['A', 'B', 'C', 'D'])
print(ret.value_counts())

"""
(0.010599999999999998, 0.364]    25
(0.364, 0.571]                   25
(0.571, 0.78]                    25
(0.78, 0.99]                     25
dtype: int64

A    25
B    25
C    25
D    25
dtype: int64
"""
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23

# 应用场景

cut和qcut的区别:
-1- cut: 按连续数据的大小分到各个桶里,每个桶里样本量可能不同,但是,每个桶相当于一个等长的区间.
     即以数据的最大和最小为边界,等分成p个桶.
-2- qcout: 与cut主要的区别就是每个桶里的样本数量是一定的.

给如下数据中的年龄制定对应的年龄段:
df = DataFrame(data=np.random.randint(10,70,size=(20,)),columns=['年龄'])
pd.cut(df['年龄'],bins=[9,20,40,70],labels=['9-20','20-40','40-70'])

Pandas提供了两种主要的分箱方法:cut和qcut.这一选择取决于数据的特点和分析的需求.
对于偏态分布的数据,由于数据不是均匀分布,而是倾向于在某一端聚集,使用qcut通常更为合适.
这是因为qcut方法会使得每个箱子中的样本数量大致相等,从而可以有效处理偏态分布造成的数据倾斜问题.
1
2
3
4
5
6
7

# 随机抽样

随机抽样不怎么用.
概念: 给定一组数据, 先随机打乱, 再将其中的局部数据切出来.

df = pd.DataFrame(data=np.random.random(size=(100,4)),columns=['A','B','C','D'])
df.take(indices=np.random.permutation(4),axis=1).take(indices=np.random.permutation(100),axis=0)[0:20]

"""
解释:
np.random.permutation(4) 返回一个0-3的索引
df.take(indices=np.random.permutation(4),axis=1) 将df的列索引打乱,按照np.random.permutation(4)来.
"""
1
2
3
4
5
6
7
8

# ★ 数据分组

groupby函数主要的作用是进行数据的分组以及分组后地组内运算!!

# 分组+聚合

image-20240816163416326

★ 注: 分组后通常都会跟聚合操作, mean聚合操作只会对数值型的数据进行聚合.
mean是聚合操作, values_counts是非聚合操作. 所以 前者的结果中没有color相关数据, 后者的结果中有color相关数据.

截图中的示例代码如下:

import pandas as pd

df = pd.DataFrame({
    'item': ['Apple', 'Banana', 'Orange', 'Banana', 'Orange', 'Apple'],
    'price': [4, 3, 3, 2.5, 4, 2],
    'color': ['red', 'yellow', 'yellow', 'green', 'green', 'green'],
    'weight': [12, 20, 50, 30, 20, 44]
})

# 需求:将每种水果的平均价格汇总到源数据中!!
mean_price_s = df.groupby(by='item')["price"].mean() # 注: [['price']]得到的就是一个DataFrame对象
dic = mean_price_s.to_dict()
df['mean_price'] = df['item'].map(dic)
print(df)
1
2
3
4
5
6
7
8
9
10
11
12
13
14

举一反三, 统计不同颜色水果的最大重量, 将其汇总到新表格中.

color_w_max = df.groupby(by="color")["weight"].max()
dic = color_w_max.to_dict()
df["color_w_max"] = df["color"].map(dic)
print(df)

"""
     item  price   color  weight  color_w_max
0   Apple    4.0     red      12           12
1  Banana    3.0  yellow      20           50
2  Orange    3.0  yellow      50           50
3  Banana    2.5   green      30           44
4  Orange    4.0   green      20           44
5   Apple    2.0   green      44           44
"""
1
2
3
4
5
6
7
8
9
10
11
12
13
14

# 分组+transform/apply

★ 我们可以使用自定义一个聚合函数作用于分组结果上.
使用groupby分组后, 也可以使用transform和apply提供自定义函数实现更多的运算

image-20240816170258432

(´・Д・)」 通过截图中的代码,不难看出apply和transform的区别:
-1- transform返回的结果是经过映射后的结果.
-2- apply返回的是没有经过映射的结果

# 分组+agg

agg实现对分组后的结果进行多种不同形式的聚合操作.

df.groupby(by='item').agg(['max','min','sum'])
df.groupby(by='item')['price'].agg(['max','min','sum'])
1
2

image-20240816170829566


# ★数据透视

示例数据长这样:

image-20240816180220971

看示例, 示例中很多需求都可以用数据分组来实现!! 结果也是一致的.

import pandas as pd

df = pd.read_csv('./data/透视表-篮球赛.csv').head(8)

# >>> df.groupby(by=["对手"]).mean()
# index参数: 分类汇总的分类条件
df.pivot_table(index=['对手'])  

# >>> df.groupby(by=["对手","主客场"]).mean()  -- 可理解, 勇士+客为一个分组、勇士+主为一个分组
df.pivot_table(index=['对手','主客场'])  

# >>> df.groupby(by=['主客场','胜负'])[['得分','篮板','助攻']].mean()
# values参数: 需要对计算的数据进行筛选
df.pivot_table(index=['主客场','胜负'],values=['得分','篮板','助攻']) 
# Aggfunc参数: 设置我们对数据聚合时进行的函数操作,默认aggfunc='mean'计算均值
df.pivot_table(index=['主客场','胜负'],values=['得分','篮板','助攻'],aggfunc='mean')  

# >>> df.groupby(by=['主客场','胜负']).agg({'得分':'sum','篮板':'max'})
df.pivot_table(index=['主客场','胜负'],aggfunc={'得分':'sum','篮板':'max'})
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19

注: Columns参数: 可以设置列层次字段, 感觉像是一种分割数据的可选方式..

image-20240816180856368


# 项目案例

image-20240816191018104

示例代码如下:

import pandas as pd

data = pd.read_excel('./Phone.xlsx')[:5]
data
data['订单日期'].dt
data['订单日期'].dt.year
data['年'] = data['订单日期'].dt.year
data['月'] = data['订单日期'].dt.month
data['年龄段'] = pd.cut(data['年龄'],bins=[0,16,26,36,49])
data

data.groupby(by='品牌')[['销售额','数量']].sum().sort_values('数量',ascending=False)
data.groupby(by='年龄段')['数量'].sum().sort_values(ascending=False)
data.pivot_table(index=['省份名字','城市名字'],values='数量',aggfunc='sum').sort_values('数量',ascending=False)
1
2
3
4
5
6
7
8
9
10
11
12
13
14

pandas数据集成
pandas时间序列

← pandas数据集成 pandas时间序列→

最近更新
01
deepseek本地部署+知识库
02-17
02
实操-微信小程序
02-14
03
教学-cursor深度探讨
02-13
更多文章>
Theme by Vdoing | Copyright © 2023-2025 DC | One Piece
  • 跟随系统
  • 浅色模式
  • 深色模式
  • 阅读模式