文章目录

  • 统计分析
  • 类似于SQL的操作
  • 增:添加新行或增加新列
  • 删:删除表、观测行或变量列
  • 删除指定的行
  • 删除指定的列
  • 改:修改原始记录的值
  • 聚合
  • 排序
  • 多表连接


统计分析

pandas模块为我们提供了非常多的描述性统计分析的指标函数,如总和、均值、最小值、最大值等,我们来具体看看这些函数:

首先随机生成三组数据

In [67]: np.random.seed(1234)
In [68]: d1 = pd.Series(2*np.random.normal(size = 100)+3)
In [69]: d2 = np.random.f(2,4,size = 100)
In [70]: d3 = np.random.randint(1,100,size = 100)

In [71]: d1.count()  #非空元素计算
Out[71]: 100
In [72]: d1.min()    #最小值
Out[72]: -4.1270333212494705
In [73]: d1.max()    #最大值
Out[73]: 7.7819210309260658
In [74]: d1.idxmin() #最小值的位置,类似于R中的which.min函数
Out[74]: 81
In [75]: d1.idxmax() #最大值的位置,类似于R中的which.max函数
Out[75]: 39
In [76]: d1.quantile(0.1)    #10%分位数
Out[76]: 0.68701846440699277
In [77]: d1.sum()    #求和
Out[77]: 307.0224566250874
In [78]: d1.mean()   #均值
Out[78]: 3.070224566250874
In [79]: d1.median() #中位数
Out[79]: 3.204555266776845
In [80]: d1.mode()   #众数
Out[80]: Series([], dtype: float64)
In [81]: d1.var()    #方差
Out[81]: 4.005609378535085
In [82]: d1.std()    #标准差
Out[82]: 2.0014018533355777
In [83]: d1.mad()    #平均绝对偏差
Out[83]: 1.5112880411556109
In [84]: d1.skew()   #偏度
Out[84]: -0.64947807604842933
In [85]: d1.kurt()   #峰度
Out[85]: 1.2201094052398012
In [86]: d1.describe()   #一次性输出多个描述性统计指标
Out[86]:
count    100.000000
mean       3.070225
std        2.001402
min       -4.127033
25%        2.040101
50%        3.204555
75%        4.434788
max        7.781921
dtype: float64

必须注意的是,describe方法只能针对序列或数据框,一维数组(numpy.ndarray)是没有这个方法的

这里自定义一个函数,将这些统计描述指标全部汇总到一起:

In [87]: def stats(x):
    ...:     return pd.Series([x.count(),x.min(),x.idxmin(),
    ...:                x.quantile(.25),x.median(),
    ...:                x.quantile(.75),x.mean(),
    ...:                x.max(),x.idxmax(),
    ...:                x.mad(),x.var(),
    ...:                x.std(),x.skew(),x.kurt()],
    ...:               index = ['Count','Min','Whicn_Min',
    ...:                        'Q1','Median','Q3','Mean',
    ...:                        'Max','Which_Max','Mad',
    ...:                        'Var','Std','Skew','Kurt'])

In [88]: stats(d1)
Out[88]:
Count        100.000000
Min           -4.127033
Whicn_Min     81.000000
Q1             2.040101
Median         3.204555
Q3             4.434788
Mean           3.070225
Max            7.781921
Which_Max     39.000000
Mad            1.511288
Var            4.005609
Std            2.001402
Skew          -0.649478
Kurt           1.220109
dtype: float64

在实际的工作中,我们可能需要处理的是一系列的数值型数据框,如何将这个函数应用到数据框中的每一列呢?可以使用apply函数,参数axis默认为0,将函数应用到数据框的每一列;设置为1时,则将函数应用到每一行。

将之前创建的d1,d2,d3数据构建数据框:

In [89]: df = pd.DataFrame(np.array([d1,d2,d3]).T,columns=['x1','x2','x3'])
In [90]: df.head()
Out[90]:
         x1        x2    x3
0  3.942870  1.369531  55.0
1  0.618049  0.943264  68.0
2  5.865414  0.590663  73.0
3  2.374696  0.206548  59.0
4  1.558823  0.223204  60.0

In [91]: df.apply(stats)
Out[91]:
                   x1          x2          x3
Count      100.000000  100.000000  100.000000
Min         -4.127033    0.014330    3.000000
Whicn_Min   81.000000   72.000000   76.000000
Q1           2.040101    0.249580   25.000000
Median       3.204555    1.000613   54.500000
Q3           4.434788    2.101581   73.000000
Mean         3.070225    2.028608   51.490000
Max          7.781921   18.791565   98.000000
Which_Max   39.000000   53.000000   96.000000
Mad          1.511288    1.922669   24.010800
Var          4.005609   10.206447  780.090808
Std          2.001402    3.194753   27.930106
Skew        -0.649478    3.326246   -0.118917
Kurt         1.220109   12.636286   -1.211579

非常完美,就这样很简单的创建了数值型数据的统计性描述。如果是离散型数据呢?就不能用这个统计口径了,我们需要统计离散变量的观测数、唯一值个数、众数水平及个数。你只需要使用describe方法就可以实现这样的统计了。

In [92]: student['Sex'].describe()
Out[92]:
count     19 # 有多少个样本
unique     2 # 唯一值个数
top        M # 众数
freq      10 # 众数出现的次数
Name: Sex, dtype: object

除以上的简单描述性统计之外,还提供了连续变量的相关系数(corr)和协方差矩阵(cov)的求解,这个跟R语言是一致的用法。

In [93]: df.corr() # 返回pair-wise相关系数,所以是一个对称矩阵
Out[93]:
          x1        x2        x3
x1  1.000000  0.136085  0.037185
x2  0.136085  1.000000 -0.005688
x3  0.037185 -0.005688  1.000000

关于相关系数的计算可以调用pearson方法或kendell方法或spearman方法,默认使用pearson方法。

In [94]: df.corr('spearman')
Out[94]:
         x1        x2        x3
x1  1.00000  0.178950  0.006590
x2  0.17895  1.000000 -0.033874
x3  0.00659 -0.033874  1.000000

如果只想关注某一个变量与其余变量的相关系数的话,可以使用corrwith,如下方只关心x1与其余变量的相关系数:

In [95]: df.corrwith(df['x1'])
Out[95]:
x1    1.000000
x2    0.136085
x3    0.037185
dtype: float64

数值型数据的协方差矩阵:

In [96]: df.cov()
Out[96]:
          x1         x2          x3
x1  4.005609   0.870124    2.078596
x2  0.870124  10.206447   -0.507512
x3  2.078596  -0.507512  780.090808

类似于SQL的操作

在SQL中常见的操作主要是增、删、改、查几个动作,那么pandas能否实现对数据的这几项操作呢?答案是Of Course!

增:添加新行或增加新列

In [99]: dic = {'Name':['LiuShunxiang','Zhangshan'],
    ...:        'Sex':['M','F'],'Age':[27,23],
    ...:        'Height':[165.7,167.2],'Weight':[61,63]}

In [100]: student2 = pd.DataFrame(dic)

In [101]: student2
Out[101]:
   Age  Height          Name Sex  Weight
0   27   165.7  LiuShunxiang   M      61
1   23   167.2     Zhangshan   F      63

现在将student2中的数据新增到student中,可以通过concat函数实现:

python A列 pythona列的平均值_python A列

注意到了吗?在数据库中union必须要求两张表的列顺序一致,而这里concat函数可以自动对齐两个数据框的变量(前面student数据框列的顺序是’Name Sex Age Height Weight’,和student2定义的列顺序不同,但是合并时按列名进行了对齐)!

新增列的话,其实在pandas中就更简单了,例如在student2中新增一列学生成绩:

python A列 pythona列的平均值_python_02

对于新增的列没有赋值,就会出现空NaN的形式。

补充一下,也可以这样初始化并新增一列:

>>> df = pd.DataFrame({'a':[1,2],'b':[3,4]})
>>> df
   a  b
0  1  3
1  2  4
>>> df['c'] = 0
>>> df
   a  b  c
0  1  3  0
1  2  4  0

删:删除表、观测行或变量列

删除数据框student2,通过del命令实现,该命令可以删除Python的所有对象。

python A列 pythona列的平均值_数据分析_03

删除指定的行

python A列 pythona列的平均值_数据库_04

原数据中的第1,2,4,7行的数据已经被删除了。

根据布尔索引删除行数据,其实这个删除就是保留删除条件的反面数据,例如删除所有14岁以下的学生:

python A列 pythona列的平均值_数据库_05

删除指定的列

python A列 pythona列的平均值_数据分析_06

我们发现,不论是删除行还是删除列,都可以通过drop方法实现,只需要设定好删除的轴即可,即调整drop方法中的axis参数。默认该参数为0,表示删除行观测,如果需要删除列变量,则需设置为1

改:修改原始记录的值

如果发现表中的某些数据错误了,如何更改原来的值呢?我们试试结合布尔索引和赋值的方法:

例如发现student3中姓名为Liushunxiang的学生身高错了,应该是173,如何改呢?

python A列 pythona列的平均值_python A列_07

这样就可以把原来的身高修改为现在的170了。

看,关于索引的操作非常灵活、方便吧,就这样轻松搞定数据的更改。

有关数据查询部分,上面已经介绍过,下面重点讲讲聚合、排序和多表连接操作。

聚合

pandas模块中可以通过groupby()函数实现数据的聚合操作

根据性别分组,计算各组别中学生身高和体重的平均值:

python A列 pythona列的平均值_python A列_08

如果不对原始数据作限制的话,聚合函数会自动选择数值型数据进行聚合计算。如果不想对年龄计算平均值的话,就需要剔除改变量:

python A列 pythona列的平均值_数据分析_09

groupby还可以使用多个分组变量,例如根本年龄和性别分组,计算身高与体重的平均值:

python A列 pythona列的平均值_python A列_10

当然,还可以对每个分组计算多个统计量

python A列 pythona列的平均值_数据分析_11

是不是很简单,只需一句就能完成SQL中的SELECT…FROM…GROUP BY…功能,何乐而不为呢?

排序

排序在日常的统计分析中还是比较常见的操作,我们可以使用order、sort_index和sort_values实现序列和数据框的排序工作:

python A列 pythona列的平均值_数据库_12

我们再试试降序排序的设置:

python A列 pythona列的平均值_数据库_13

上面两个结果其实都是按值排序,并且结果中都给出了警告信息,即建议使用sort_values()函数进行按值排序

在数据框中一般都是按值排序,例如:

python A列 pythona列的平均值_数据分析_14

多表连接

多表之间的连接也是非常常见的数据库操作,连接分内连接外连接,在数据库语言中通过join关键字实现,pandas我比较建议使用merge函数实现数据的各种连接操作。

如下是构造一张学生的成绩表:

python A列 pythona列的平均值_python A列_15

现在想把学生表student与学生成绩表score做一个关联,该如何操作呢?

python A列 pythona列的平均值_数据分析_16

注意,默认情况下,merge函数实现的是两个表之间的内连接,即返回两张表中共同部分的数据。可以通过how参数设置连接的方式,left为左连接;right为右连接;outer为外连接。

python A列 pythona列的平均值_java_17

左连接实现的是保留student表中的所有信息,同时将score表的信息与之配对,能配多少配多少,对于没有配对上的Name,将会显示成绩为NaN