首页 > 技术文章 > [Python] Pandas 数据表的处理和数据运算

feily 2021-02-11 17:36 原文

1. 数据表的处理

1.1 转置数据表的行列

>>> import pandas as pd
>>> data = pd.read_csv('D:\git\python\code\第5章\产品统计表.csv')
>>> a = data.T
>>> print(a)
             0     1     2     3      4     5     6
编号        a001  a002  a003  a004   a005  a006  a007
产品          背包    钱包    背包   手提包     钱包   单肩包   单肩包
成本价(元/个)    16    90    16    36     90    58    58
销售价(元/个)    65   187    65   147    187   124   124
数量(个)       60    50    23    26     78    63    58
成本(元)      960  4500   368   936   7020  3654  3364
收入(元)     3900  9350  1495  3822  14586  7812  7192
利润(元)     2940  4850  1127  2886   7566  4158  3828

1.2 将数据表转换为树形结构

将数据表转换为树形结构就是在维持二维表格的行标签不变的情况下,把列标签也变成行标签,通俗来讲,就是为二维表格建立层次化的索引。

>>> data = pd.read_excel('D:\git\python\code\第5章\产品统计表3.xlsx')
>>> print(data)
     编号   产品  销售价(元/个)  数量(个)   收入(元)
0  a001   背包      65.0   60.0  3900.0
1  a002   钱包     187.0   50.0  9350.0
2  a003  单肩包     124.0   58.0  7192.0

用stack()函数将上述数据表转换为树形结构。

>>> print(data.stack())
0  编号            a001
   产品              背包
   销售价(元/个)      65.0
   数量(个)         60.0
   收入(元)       3900.0
1  编号            a002
   产品              钱包
   销售价(元/个)     187.0
   数量(个)         50.0
   收入(元)       9350.0
2  编号            a003
   产品             单肩包
   销售价(元/个)     124.0
   数量(个)         58.0
   收入(元)       7192.0
dtype: object

1.3 数据表的拼接

数据表的拼接是指将两个或多个数据表合并为一个数据表,主要会用到pandas模块中的merge()函数、concat()函数和append()函数。

merge()函数

>>> data1 = pd.read_excel('D:\git\python\code\第5章\产品表.xlsx', sheet_name=0)
>>> data2 = pd.read_excel('D:\git\python\code\第5章\产品表.xlsx', sheet_name=1)
>>> print(data1)
   员工编号 员工姓名 员工性别
0  a001   张三    男
1  a002   李四    女
2  a003   王五    男
3  a004   赵六    男
>>> print(data2)
   员工编号 员工姓名      销售业绩
0  a001   张三  360000.0
1  a002   李四  458000.0
2  a003   王五  369000.0
3  a004   赵六  450000.0
4  a005   钱七  500000.0
>>> print(pd.merge(data1,data2))
   员工编号 员工姓名 员工性别      销售业绩
0  a001   张三    男  360000.0
1  a002   李四    女  458000.0
2  a003   王五    男  369000.0
3  a004   赵六    男  450000.0
>>> print(pd.merge(data1,data2,how='outer'))
   员工编号 员工姓名 员工性别      销售业绩
0  a001   张三    男  360000.0
1  a002   李四    女  458000.0
2  a003   王五    男  369000.0
3  a004   赵六    男  450000.0
4  a005   钱七  NaN  500000.0

想合并两个表的所有数据,则需要为merge()函数添加参数how,并设置其值为'outer'。

如果两个表中相同的列标签不止一个,可以利用参数on来指定依据哪一列进行合并操作。

>>> print(pd.merge(data1,data2,on='员工编号'))
   员工编号 员工姓名_x 员工性别 员工姓名_y      销售业绩
0  a001     张三    男     张三  360000.0
1  a002     李四    女     李四  458000.0
2  a003     王五    男     王五  369000.0
3  a004     赵六    男     赵六  450000.0

concat()函数

concat()函数采用的是全连接数据的方式,它可以直接将两个或多个数据表合并,即不需要两表的某些列或索引相同,也可以把数据整合到一起。

>>> print(pd.concat([data1,data2]))
   员工编号 员工姓名 员工性别      销售业绩
0  a001   张三    男       NaN
1  a002   李四    女       NaN
2  a003   王五    男       NaN
3  a004   赵六    男       NaN
0  a001   张三  NaN  360000.0
1  a002   李四  NaN  458000.0
2  a003   王五  NaN  369000.0
3  a004   赵六  NaN  450000.0
4  a005   钱七  NaN  500000.0

合并后的表中每一行的行标签仍然为原先两个表各自的行标签,如果想要重置行标签,可以在concat()函数中设置参数ignore_index为True。

>>> print(pd.concat([data1,data2], ignore_index=True))
   员工编号 员工姓名 员工性别      销售业绩
0  a001   张三    男       NaN
1  a002   李四    女       NaN
2  a003   王五    男       NaN
3  a004   赵六    男       NaN
4  a001   张三  NaN  360000.0
5  a002   李四  NaN  458000.0
6  a003   王五  NaN  369000.0
7  a004   赵六  NaN  450000.0
8  a005   钱七  NaN  500000.0

append()函数

append()函数的用法比较简单,它可以直接将一个或多个数据表中的数据合并到其他数据表中。

data1.append(data2)

和 print(pd.concat([data1,data2])) 结果一样

>>> g = data1.append({'员工编号':'a005','员工姓名':'孙七','员工性别':'男'}, ignore_index=True)
>>> print(g)
   员工编号 员工姓名 员工性别
0  a001   张三    男
1  a002   李四    女
2  a003   王五    男
3  a004   赵六    男
4  a005   孙七    男

2. 数据的运算

有数据的统计运算、数值分布情况的获取、相关系数的计算、数据的分组汇总、数据透视表的创建。

2.1 数据的统计运算

常见的统计运算包括求和、求平均值、求最值,分别要用到sum()函数、mean()函数、max()函数和min()函数。

求和

>>> data = pd.read_csv('D:\git\python\code\第5章\产品统计表.csv')
>>> print(data.sum())
编号          a001a002a003a004a005a006a007
产品                     背包钱包背包手提包钱包单肩包单肩包
成本价(元/个)                             364
销售价(元/个)                             899
数量(个)                                358
成本(元)                              20802
收入(元)                              48157
利润(元)                              27355
dtype: object
>>> print(data['利润(元)'].sum())
27355

对于非数值数据,运算结果是将它们依次连接得到的一个字符串;对于数值数据,运算结果才是数据之和。

求平均值、求最值

>>> print(data['利润(元)'].mean())
3907.8571428571427
>>> print(data['利润(元)'].max())
>>> data
     编号   产品  成本价(元/个)  销售价(元/个)  数量(个)  成本(元)  收入(元)  利润(元)
0  a001   背包        16        65     60    960   3900   2940
1  a002   钱包        90       187     50   4500   9350   4850
2  a003   背包        16        65     23    368   1495   1127
3  a004  手提包        36       147     26    936   3822   2886
4  a005   钱包        90       187     78   7020  14586   7566
5  a006  单肩包        58       124     63   3654   7812   4158
6  a007  单肩包        58       124     58   3364   7192   3828
>>> data.min()
编号          a001
产品           单肩包
成本价(元/个)      16
销售价(元/个)      65
数量(个)         23
成本(元)        368
收入(元)       1495
利润(元)       1127
dtype: object

2.2 获取数值分布情况

pandas模块中的describe()函数可以按列获取数据表中所有数值数据的分布情况,包括数据的个数、均值、最值、方差、分位数等。

>>> data.describe()
        成本价(元/个)    销售价(元/个)      数量(个)        成本(元)         收入(元)        利润(元)
count   7.000000    7.000000   7.000000     7.000000      7.000000     7.000000
mean   52.000000  128.428571  51.142857  2971.714286   6879.571429  3907.857143
std    31.112698   50.483849  20.053500  2391.447659   4352.763331  2002.194498
min    16.000000   65.000000  23.000000   368.000000   1495.000000  1127.000000
25%    26.000000   94.500000  38.000000   948.000000   3861.000000  2913.000000
50%    58.000000  124.000000  58.000000  3364.000000   7192.000000  3828.000000
75%    74.000000  167.000000  61.500000  4077.000000   8581.000000  4504.000000
max    90.000000  187.000000  78.000000  7020.000000  14586.000000  7566.000000
>>> data['利润(元)'].describe()
count       7.000000
mean     3907.857143
std      2002.194498
min      1127.000000
25%      2913.000000
50%      3828.000000
75%      4504.000000
max      7566.000000
Name: 利润(元), dtype: float64

2.3 计算相关系数

相关系数通常用来衡量两个或多个元素之间的相关程度,使用pandas模块中的corr()函数可以计算相关系数。

>>> data = pd.read_excel('D:\git\python\code\第5章\相关性分析.xlsx')
>>> print(data)
   代理商编号  年销售额(万元)  年广告费投入额(万元)  成本费用(万元)  管理费用(万元)
0  A-001      20.5         15.6      2.00      0.80
1  A-003      24.5         16.7      2.54      0.94
2  B-002      31.8         20.4      2.96      0.88
3  B-006      34.9         22.6      3.02      0.79
4  B-008      39.4         25.7      3.14      0.84
5  C-003      44.5         28.8      4.00      0.80
6  C-004      49.6         32.1      6.84      0.85
7  C-007      54.8         35.9      5.60      0.91
8  D-006      58.5         38.7      6.45      0.90
>>> data.corr()
             年销售额(万元)  年广告费投入额(万元)  成本费用(万元)  管理费用(万元)
年销售额(万元)     1.000000     0.996275  0.914428  0.218317
年广告费投入额(万元)  0.996275     1.000000  0.918404  0.223187
成本费用(万元)     0.914428     0.918404  1.000000  0.284286
管理费用(万元)     0.218317     0.223187  0.284286  1.000000

如果只想查看某一列与其他列的相关系数,可以用列标签来指定列。

>>> data.corr()['年销售额(万元)']
年销售额(万元)       1.000000
年广告费投入额(万元)    0.996275
成本费用(万元)       0.914428
管理费用(万元)       0.218317
Name: 年销售额(万元), dtype: float64

2.4 分组汇总数据

pandas模块中的groupby()函数可以对数据进行分组。

>>> data = pd.read_csv('D:\git\python\code\第5章\产品统计表.csv')
>>> data
     编号   产品  成本价(元/个)  销售价(元/个)  数量(个)  成本(元)  收入(元)  利润(元)
0  a001   背包        16        65     60    960   3900   2940
1  a002   钱包        90       187     50   4500   9350   4850
2  a003   背包        16        65     23    368   1495   1127
3  a004  手提包        36       147     26    936   3822   2886
4  a005   钱包        90       187     78   7020  14586   7566
5  a006  单肩包        58       124     63   3654   7812   4158
6  a007  单肩包        58       124     58   3364   7192   3828
>>> data.groupby('产品')['数量(个)','利润(元)'].sum()
     数量(个)  利润(元)
产品               
单肩包    121   7986
手提包     26   2886
背包      83   4067
钱包     128  12416

2.5 创建数据透视表

数据透视表可对数据表中的数据进行快速分组和计算。pandas模块中的pivot_table()函数可以制作数据透视表。

>>> pd.pivot_table(data, values=['利润(元)','成本(元)'], index='产品', aggfunc='sum')
     利润(元)  成本(元)
产品               
单肩包   7986   7018
手提包   2886    936
背包    4067   1328
钱包   12416  11520
>>> pd.pivot_table(data, values=['利润(元)','成本(元)'], index=['产品','编号'], aggfunc='sum')
          利润(元)  成本(元)
产品  编号                
单肩包 a006   4158   3654
    a007   3828   3364
手提包 a004   2886    936
背包  a001   2940    960
    a003   1127    368
钱包  a002   4850   4500
    a005   7566   7020

推荐阅读