文章目录
- 统计分析
- 类似于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函数实现:
注意到了吗?在数据库中union必须要求两张表的列顺序一致,而这里concat函数可以自动对齐两个数据框的变量(前面student数据框列的顺序是’Name Sex Age Height Weight’,和student2定义的列顺序不同,但是合并时按列名进行了对齐)!
新增列的话,其实在pandas中就更简单了,例如在student2中新增一列学生成绩:
对于新增的列没有赋值,就会出现空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的所有对象。
删除指定的行
原数据中的第1,2,4,7行的数据已经被删除了。
根据布尔索引删除行数据,其实这个删除就是保留删除条件的反面数据,例如删除所有14岁以下的学生:
删除指定的列
我们发现,不论是删除行还是删除列,都可以通过drop方法实现,只需要设定好删除的轴即可,即调整drop方法中的axis参数。默认该参数为0,表示删除行观测,如果需要删除列变量,则需设置为1。
改:修改原始记录的值
如果发现表中的某些数据错误了,如何更改原来的值呢?我们试试结合布尔索引和赋值的方法:
例如发现student3中姓名为Liushunxiang的学生身高错了,应该是173,如何改呢?
这样就可以把原来的身高修改为现在的170了。
看,关于索引的操作非常灵活、方便吧,就这样轻松搞定数据的更改。
查
有关数据查询部分,上面已经介绍过,下面重点讲讲聚合、排序和多表连接操作。
聚合
pandas模块中可以通过groupby()函数实现数据的聚合操作
根据性别分组,计算各组别中学生身高和体重的平均值:
如果不对原始数据作限制的话,聚合函数会自动选择数值型数据进行聚合计算。如果不想对年龄计算平均值的话,就需要剔除改变量:
groupby还可以使用多个分组变量,例如根本年龄和性别分组,计算身高与体重的平均值:
当然,还可以对每个分组计算多个统计量:
是不是很简单,只需一句就能完成SQL中的SELECT…FROM…GROUP BY…功能,何乐而不为呢?
排序
排序在日常的统计分析中还是比较常见的操作,我们可以使用order、sort_index和sort_values实现序列和数据框的排序工作:
我们再试试降序排序的设置:
上面两个结果其实都是按值排序,并且结果中都给出了警告信息,即建议使用sort_values()函数进行按值排序。
在数据框中一般都是按值排序,例如:
多表连接
多表之间的连接也是非常常见的数据库操作,连接分内连接和外连接,在数据库语言中通过join关键字实现,pandas我比较建议使用merge函数实现数据的各种连接操作。
如下是构造一张学生的成绩表:
现在想把学生表student与学生成绩表score做一个关联,该如何操作呢?
注意,默认情况下,merge函数实现的是两个表之间的内连接,即返回两张表中共同部分的数据。可以通过how参数设置连接的方式,left为左连接;right为右连接;outer为外连接。
左连接实现的是保留student表中的所有信息,同时将score表的信息与之配对,能配多少配多少,对于没有配对上的Name,将会显示成绩为NaN。