注:为满足财经高校师生对数据科学技术强烈的学习需求和图书馆空间改造的需要,中国财经教育资源共享联盟计划开展“数据科学空间”项目,本次财经数据科学实战训练营是项目建设内容的重要组成部分。

本次训练营的录像以及其他课程相关文件,都会在财经慕课平台发布: https://www.cjmooc.com.cn

第 3 章 Python 编程分析基础
 3.1 Python 数据类型
 3.1.1 Python 对象
 3.1.2 数据的基本类型
 3.1.3 标准数据类型
 3.2 数值分析库 numpy
 3.2.1 一维数组(向量)
 3.2.2 二维数组(矩阵)
 3.2.3 数组的操作
 3.3 数据分析库 pandas
 3.3.1 序列:Series
 3.3.2 数据框DataFrame
 3.3.3 数据框的读写
 3.3.4 数据框的操作
 3.4 Python 编程运算
 3.4.1 基本运算
 3.4.2 控制语句
 3.4.3 函数定义
 3.4.4 面向对象

第3章 Python 编程分析基础

3.1 Python 数据类型

3.1.1 Python 对象

In [1]:
#结果多项输出
from IPython.core.interactiveshell import InteractiveShell
InteractiveShell.ast_node_interactivity = "all"  
In [2]:
#查看数据对象
%who
InteractiveShell	 
In [3]:
#生成数据对象 
x=10.12 #创建对象 x
%who
InteractiveShell	 x	 
In [4]:
#删除数据对象 
del x #删除对象 x
%who
InteractiveShell	 

3.1.2 数据的基本类型

(1)数值型

In [5]:
n=10 #整数
n#无格式输出,相当于 print(n)
print("n=",n) #有格式输出
x=10.234 #实数
print(x) 
print("x=%10.5f"%x)
Out[5]:
10
n= 10
10.234
x=  10.23400

(2)逻辑型

In [6]:
a=True;a 
b=False;b
Out[6]:
True
Out[6]:
False
In [7]:
10>3
10<3
Out[7]:
True
Out[7]:
False

(3)字符型

In [8]:
s = 'I love Python';s
s[7]
s[2:6] 
s+s 
s*2
Out[8]:
'I love Python'
Out[8]:
'P'
Out[8]:
'love'
Out[8]:
'I love PythonI love Python'
Out[8]:
'I love PythonI love Python'

3.1.3 标准数据类型

(1)List(列表)

In [9]:
list1 =[]          # 空列表
list1 
list1 = ['Python', 786 , 2.23, 'R', 70.2]
list1               # 输出完整列表
list1[0]            # 输出列表的第一个元素 
list1[1:3]          # 输出第二个至第三个元素 
list1[2:]           # 输出从第三个开始至列表末尾的所有元素
list1 * 2           # 输出列表两次 
list1 + list1[2:4]  # 打印组合的列表
Out[9]:
[]
Out[9]:
['Python', 786, 2.23, 'R', 70.2]
Out[9]:
'Python'
Out[9]:
[786, 2.23]
Out[9]:
[2.23, 'R', 70.2]
Out[9]:
['Python', 786, 2.23, 'R', 70.2, 'Python', 786, 2.23, 'R', 70.2]
Out[9]:
['Python', 786, 2.23, 'R', 70.2, 2.23, 'R']
In [10]:
X=[1,3,6,4,9];X
sex=['女','男','男','女','男']
sex 
weight=[67,66,83,68,70]; 
weight
Out[10]:
[1, 3, 6, 4, 9]
Out[10]:
['女', '男', '男', '女', '男']
Out[10]:
[67, 66, 83, 68, 70]

(3)Dictionary(字典)

In [11]:
{} #空字典
dict1={'name':'john','code':6734,'dept':'sales'};dict1 #定义字典 
dict1['code'] # 输出键为'code' 的值
dict1.keys() # 输出所有键 
dict1.values() # 输出所有值
Out[11]:
{}
Out[11]:
{'code': 6734, 'dept': 'sales', 'name': 'john'}
Out[11]:
6734
Out[11]:
dict_keys(['name', 'code', 'dept'])
Out[11]:
dict_values(['john', 6734, 'sales'])
In [12]:
dict2={'sex': sex,'weight':weight}; dict2 #根据列表构成字典
Out[12]:
{'sex': ['女', '男', '男', '女', '男'], 'weight': [67, 66, 83, 68, 70]}

3.2 数值分析库 numpy

3.2.1 一维数组(向量)

In [13]:
import numpy as np #加载数组包
np.array([1,2,3,4,5]) #一维数组
Out[13]:
array([1, 2, 3, 4, 5])
In [14]:
np.array([1,2,3,np.nan,5]) #包含缺失值的数
Out[14]:
array([ 1.,  2.,  3., nan,  5.])
In [15]:
np.arange(9) #数组序列 
np.arange(1,9,0.5) #等差数列 
np.linspace(1,9,5) #等距数列
Out[15]:
array([0, 1, 2, 3, 4, 5, 6, 7, 8])
Out[15]:
array([1. , 1.5, 2. , 2.5, 3. , 3.5, 4. , 4.5, 5. , 5.5, 6. , 6.5, 7. ,
       7.5, 8. , 8.5])
Out[15]:
array([1., 3., 5., 7., 9.])

3.2.2 二维数组(矩阵)

In [16]:
np.array([[1,2],[3,4],[5,6]]) #二维数组
Out[16]:
array([[1, 2],
       [3, 4],
       [5, 6]])
In [17]:
A=np.arange(9).reshape((3,3));A #形成 3×3 矩阵
Out[17]:
array([[0, 1, 2],
       [3, 4, 5],
       [6, 7, 8]])

3.2.3 数组的操作

(1)数组的维度

In [18]:
A.shape
Out[18]:
(3, 3)

(2)空数组

In [19]:
np.empty([3,3]) 
Out[19]:
array([[2.37663529e-312, 2.14321575e-312, 2.37663529e-312],
       [2.56761491e-312, 1.93101617e-312, 9.33678148e-313],
       [1.97345609e-312, 6.79038653e-313, 1.89144180e-307]])

(3)零数组

In [20]:
np.zeros((3,3))  #零矩阵 
Out[20]:
array([[0., 0., 0.],
       [0., 0., 0.],
       [0., 0., 0.]])

(4) 1数组

In [21]:
np.ones((3,3)) #1矩阵
Out[21]:
array([[1., 1., 1.],
       [1., 1., 1.],
       [1., 1., 1.]])

(5)单位阵

In [22]:
np.eye(3)
Out[22]:
array([[1., 0., 0.],
       [0., 1., 0.],
       [0., 0., 1.]])

3.3 数据分析库 pandas

3.3.1 序列:Series

(2)生成序列

In [23]:
import pandas as pd #加载数据分析包
pd.Series() #生成空序列 
Out[23]:
Series([], dtype: float64)

(3)根据列表构建序列

In [24]:
X=[1,3,6,4,9]
S1=pd.Series(X);S1 
S2=pd.Series(weight);S2 
S3=pd.Series(sex);S3
Out[24]:
0    1
1    3
2    6
3    4
4    9
dtype: int64
Out[24]:
0    67
1    66
2    83
3    68
4    70
dtype: int64
Out[24]:
0    女
1    男
2    男
3    女
4    男
dtype: object

(4)序列合并

In [25]:
pd.concat([S2,S3],axis=0) #按行并序列 
pd.concat([S2,S3],axis=1) #按列并序列
Out[25]:
0    67
1    66
2    83
3    68
4    70
0     女
1     男
2     男
3     女
4     男
dtype: object
Out[25]:
0 1
0 67
1 66
2 83
3 68
4 70

(5)序列切片

In [26]:
S1[2] 
S3[1:4]
Out[26]:
6
Out[26]:
1    男
2    男
3    女
dtype: object

3.3.2 数据框:DataFrame

(1)生成数据框

In [27]:
pd.DataFrame()  
Out[27]:

(2)根据列表创建数据框

In [28]:
pd.DataFrame(X) 
pd.DataFrame(X, columns=['X'], index=range(5)) 
pd.DataFrame(weight,columns=['weight'], index=['A','B','C','D','E'])
Out[28]:
0
0 1
1 3
2 6
3 4
4 9
Out[28]:
X
0 1
1 3
2 6
3 4
4 9
Out[28]:
weight
A 67
B 66
C 83
D 68
E 70

(3)根据字典创建数据框

In [29]:
df1=pd.DataFrame({'S1':S1,'S2':S2,'S3':S3}); df1 
Out[29]:
S1 S2 S3
0 1 67
1 3 66
2 6 83
3 4 68
4 9 70
In [30]:
df2=pd.DataFrame({'sex':sex,'weight':weight},index=X);df2 
Out[30]:
sex weight
1 67
3 66
6 83
4 68
9 70

(4)增加数据框列

In [31]:
df2['weight2']=df2['weight']**2; df2 
Out[31]:
sex weight weight2
1 67 4489
3 66 4356
6 83 6889
4 68 4624
9 70 4900

(5)删除数据框列

In [32]:
del df2['weight2']; df2
Out[32]:
sex weight
1 67
3 66
6 83
4 68
9 70

(6)缺失值处理

In [33]:
df3=pd.DataFrame({'S2':S2,'S3':S3},index=S1);df3 
Out[33]:
S2 S3
1 66.0
3 68.0
6 NaN NaN
4 70.0
9 NaN NaN
In [34]:
df3.isnull() #是缺失值则返回 True,否则返回 False 
Out[34]:
S2 S3
1 False False
3 False False
6 True True
4 False False
9 True True
In [35]:
df3.isnull().sum() #返回每列包含的缺失值的个数 
Out[35]:
S2    2
S3    2
dtype: int64
In [36]:
df3.dropna() #直接删除含有缺失值的行,多变量谨慎使用 
Out[36]:
S2 S3
1 66.0
3 68.0
4 70.0

(7)数据框排序

In [37]:
df3.sort_index() #按 index 排序 
Out[37]:
S2 S3
1 66.0
3 68.0
4 70.0
6 NaN NaN
9 NaN NaN
In [38]:
df3.sort_values(by='S3') #按列值排序 
Out[38]:
S2 S3
3 68.0
1 66.0
4 70.0
6 NaN NaN
9 NaN NaN

3.3.3 数据框的读写

3.3.3.1 pandas 读取数据集

(1)从剪切板上读取,先在 DaPy_data.xls 数据文件的【BSdata】表中选取 A1:H53,复制,然后在 Python 中读取数据。

In [3]:
import pandas as pd
BSdata=pd.read_clipboard(); #从剪切板上复制数据 
BSdata[:5] #BSdata.head() 见下节
Out[3]:
所用时间 来源 来源详情 来自IP
0 183 微信 NaN 119.62.31.172(云南-昆明)
1 235 微信 NaN 103.98.241.233(湖北-武汉)
2 279 微信 NaN 106.61.38.118(云南-昆明)
3 86 微信 NaN 124.238.74.0(河北-沧州)
4 171 微信 NaN 112.224.4.124(山东-济南)

(2)读取 csv 格式数据

In [48]:
# BSdata=pd.read_csv("BSdata.csv",encoding='utf-8') #注意中文格式
BSdata=pd.read_csv("BSdata.csv",encoding='gbk') #注意中文格式

BSdata[6:9]
Out[48]:
学号 性别 身高 体重 支出 开设 课程 软件
6 1516352030 169 71 9.1 有必要 编程技术 Excel
7 1516171019 166 66 2.5 不必要 都未学过 Excel
8 1516391008 165 69 35.6 不必要 都未学过 Excel

(3)读取 Excel 格式数据

In [49]:
BSdata=pd.read_excel('DaPy_data.xlsx','BSdata');BSdata[-5:] 
Out[49]:
学号 性别 身高 体重 支出 开设 课程 软件
47 1538319004 175 68 44.4 不清楚 统计方法 SAS
48 1538254010 166 65 5.3 不清楚 编程技术 Python
49 1540294017 159 58 71.4 不清楚 都学习过 SPSS
50 1540365026 169 73 5.5 有必要 统计方法 Excel
51 1540388036 165 67 56.8 不必要 概率统计 SAS
3.3.3.2 pandas 数据集的保存
In [50]:
 #将数据框 BSdata 保存到 BSdata.csv 文档中
BSdata.to_csv('BSdata1.csv')
In [51]:
#将数据框 BSdata 保存到BSdata1.xlsx 文档中
BSdata.to_excel('BSdata1.xlsx',index=False)

3.3.4 数据框的操作

3.3.4.1 基本信息

(1)数据框显示

In [52]:
 BSdata.info() #数据框信息
<class 'pandas.core.frame.DataFrame'>
RangeIndex: 52 entries, 0 to 51
Data columns (total 8 columns):
学号    52 non-null int64
性别    52 non-null object
身高    52 non-null int64
体重    52 non-null int64
支出    52 non-null float64
开设    52 non-null object
课程    52 non-null object
软件    52 non-null object
dtypes: float64(1), int64(3), object(4)
memory usage: 3.4+ KB
In [53]:
BSdata.head() #显示前 5 行 
BSdata.tail() #显示后 5 行
Out[53]:
学号 性别 身高 体重 支出 开设 课程 软件
0 1510248008 167 71 46.0 不清楚 都未学过 No
1 1510229019 171 68 10.4 有必要 概率统计 Matlab
2 1512108019 175 73 21.0 有必要 统计方法 SPSS
3 1512332010 169 74 4.9 有必要 编程技术 Excel
4 1512331015 154 55 25.9 有必要 都学习过 Python
Out[53]:
学号 性别 身高 体重 支出 开设 课程 软件
47 1538319004 175 68 44.4 不清楚 统计方法 SAS
48 1538254010 166 65 5.3 不清楚 编程技术 Python
49 1540294017 159 58 71.4 不清楚 都学习过 SPSS
50 1540365026 169 73 5.5 有必要 统计方法 Excel
51 1540388036 165 67 56.8 不必要 概率统计 SAS

(2)数据框列名(变量名)

In [54]:
BSdata.columns #查看列名称 
Out[54]:
Index(['学号', '性别', '身高', '体重', '支出', '开设', '课程', '软件'], dtype='object')

(3)数据框行名(样品名)

In [55]:
BSdata.index #数据框行名 
Out[55]:
RangeIndex(start=0, stop=52, step=1)

(4)数据框维度

In [56]:
BSdata.shape #显示数据框的行数和列数
BSdata.shape[0] #数据框行数 
BSdata.shape[1] #数据框列数
Out[56]:
(52, 8)
Out[56]:
52
Out[56]:
8

(5)数据框值(数组)

In [57]:
BSdata.values[:5] #数据框值数组 
Out[57]:
array([[1510248008, '女', 167, 71, 46.0, '不清楚', '都未学过', 'No'],
       [1510229019, '男', 171, 68, 10.4, '有必要', '概率统计', 'Matlab'],
       [1512108019, '女', 175, 73, 21.0, '有必要', '统计方法', 'SPSS'],
       [1512332010, '男', 169, 74, 4.9, '有必要', '编程技术', 'Excel'],
       [1512331015, '男', 154, 55, 25.9, '有必要', '都学习过', 'Python']],
      dtype=object)
3.3.4.2 选取变量

(1)“.”法或[' ']:

In [58]:
BSdata.身高 #取一列数据,BSdata['身高'] 
Out[58]:
0     167
1     171
2     175
3     169
4     154
5     183
6     169
7     166
8     165
9     173
10    184
11    163
12    162
13    168
14    164
15    180
16    158
17    179
18    163
19    160
20    168
21    185
22    174
23    167
24    160
25    163
26    155
27    178
28    170
29    164
30    172
31    178
32    186
33    171
34    156
35    166
36    176
37    178
38    155
39    163
40    158
41    167
42    173
43    174
44    164
45    169
46    166
47    175
48    166
49    159
50    169
51    165
Name: 身高, dtype: int64
In [59]:
BSdata[['身高','体重']] #取两列数据 
Out[59]:
身高 体重
0 167 71
1 171 68
2 175 73
3 169 74
4 154 55
5 183 76
6 169 71
7 166 66
8 165 69
9 173 63
10 184 82
11 163 66
12 162 63
13 168 72
14 164 66
15 180 81
16 158 63
17 179 75
18 163 65
19 160 62
20 168 70
21 185 83
22 174 76
23 167 72
24 160 62
25 163 65
26 155 50
27 178 78
28 170 70
29 164 58
30 172 71
31 178 77
32 186 87
33 171 69
34 156 56
35 166 68
36 176 78
37 178 78
38 155 54
39 163 62
40 158 60
41 167 68
42 173 70
43 174 71
44 164 62
45 169 65
46 166 70
47 175 68
48 166 65
49 159 58
50 169 73
51 165 67

(2)下标法:

In [60]:
BSdata.iloc[:,2] #取 1 列 
BSdata.iloc[:,2:4] #取 3、4 列 
Out[60]:
0     167
1     171
2     175
3     169
4     154
5     183
6     169
7     166
8     165
9     173
10    184
11    163
12    162
13    168
14    164
15    180
16    158
17    179
18    163
19    160
20    168
21    185
22    174
23    167
24    160
25    163
26    155
27    178
28    170
29    164
30    172
31    178
32    186
33    171
34    156
35    166
36    176
37    178
38    155
39    163
40    158
41    167
42    173
43    174
44    164
45    169
46    166
47    175
48    166
49    159
50    169
51    165
Name: 身高, dtype: int64
Out[60]:
身高 体重
0 167 71
1 171 68
2 175 73
3 169 74
4 154 55
5 183 76
6 169 71
7 166 66
8 165 69
9 173 63
10 184 82
11 163 66
12 162 63
13 168 72
14 164 66
15 180 81
16 158 63
17 179 75
18 163 65
19 160 62
20 168 70
21 185 83
22 174 76
23 167 72
24 160 62
25 163 65
26 155 50
27 178 78
28 170 70
29 164 58
30 172 71
31 178 77
32 186 87
33 171 69
34 156 56
35 166 68
36 176 78
37 178 78
38 155 54
39 163 62
40 158 60
41 167 68
42 173 70
43 174 71
44 164 62
45 169 65
46 166 70
47 175 68
48 166 65
49 159 58
50 169 73
51 165 67
3.3.4.3 提取样品
In [61]:
BSdata.loc[3] #取 1 行 
Out[61]:
学号    1512332010
性别             男
身高           169
体重            74
支出           4.9
开设           有必要
课程          编程技术
软件         Excel
Name: 3, dtype: object
In [62]:
BSdata.loc[3:5] #取 3 至 5 行 
Out[62]:
学号 性别 身高 体重 支出 开设 课程 软件
3 1512332010 169 74 4.9 有必要 编程技术 Excel
4 1512331015 154 55 25.9 有必要 都学习过 Python
5 1516248014 183 76 85.6 不必要 编程技术 Excel
3.3.4.5 条件选取
In [63]:
BSdata[BSdata['身高']>180] 
Out[63]:
学号 性别 身高 体重 支出 开设 课程 软件
5 1516248014 183 76 85.6 不必要 编程技术 Excel
10 1520100029 184 82 10.3 有必要 都学习过 SAS
21 1525352033 185 83 5.1 有必要 都学习过 SPSS
32 1530243029 186 87 9.5 不必要 都未学过 No
In [64]:
BSdata[(BSdata['身高']>180) & (BSdata['体重']<80)] 
Out[64]:
学号 性别 身高 体重 支出 开设 课程 软件
5 1516248014 183 76 85.6 不必要 编程技术 Excel
3.3.4.6 数据框的运算

(1)生成新的数据框

In [65]:
BSdata['体重指数']=BSdata['体重']/(BSdata['身高']/100)**2
round(BSdata[:5],2) 
Out[65]:
学号 性别 身高 体重 支出 开设 课程 软件 体重指数
0 1510248008 167 71 46.0 不清楚 都未学过 No 25.46
1 1510229019 171 68 10.4 有必要 概率统计 Matlab 23.26
2 1512108019 175 73 21.0 有必要 统计方法 SPSS 23.84
3 1512332010 169 74 4.9 有必要 编程技术 Excel 25.91
4 1512331015 154 55 25.9 有必要 都学习过 Python 23.19

(2)数据框的合并 concat()

In [66]:
pd.concat([BSdata.身高, BSdata.体重],axis=0) # 按行合并 axis=0
Out[66]:
0     167
1     171
2     175
3     169
4     154
     ... 
47     68
48     65
49     58
50     73
51     67
Length: 104, dtype: int64
In [67]:
pd.concat([BSdata.身高, BSdata.体重],axis=1) #按列合并 axis=1 
Out[67]:
身高 体重
0 167 71
1 171 68
2 175 73
3 169 74
4 154 55
5 183 76
6 169 71
7 166 66
8 165 69
9 173 63
10 184 82
11 163 66
12 162 63
13 168 72
14 164 66
15 180 81
16 158 63
17 179 75
18 163 65
19 160 62
20 168 70
21 185 83
22 174 76
23 167 72
24 160 62
25 163 65
26 155 50
27 178 78
28 170 70
29 164 58
30 172 71
31 178 77
32 186 87
33 171 69
34 156 56
35 166 68
36 176 78
37 178 78
38 155 54
39 163 62
40 158 60
41 167 68
42 173 70
43 174 71
44 164 62
45 169 65
46 166 70
47 175 68
48 166 65
49 159 58
50 169 73
51 165 67
In [68]:
BSdata.iloc[:3,:5].T #数据框转置 .T
Out[68]:
0 1 2
学号 1510248008 1510229019 1512108019
性别
身高 167 171 175
体重 71 68 73
支出 46 10.4 21

3.4 Python 编程运算

3.4.2 控制语句

3.4.2.1 循环语句 for
In [69]:
for i in range(1,5): 
    print(i) 
1
2
3
4
In [70]:
fruits = ['banana', 'apple', 'mango'] 
for fruit in fruits: 
    print('当前水果 :', fruit)
当前水果 : banana
当前水果 : apple
当前水果 : mango
In [71]:
for var in BSdata.columns: 
    print(var)
学号
性别
身高
体重
支出
开设
课程
软件
体重指数
3.4.2.2 条件语句 if/else
In [72]:
a = -100
if a < 100:
    print("数值小于 100") 
else: 
        print("数值大于 100")
数值小于 100
In [73]:
-a if a<0 else a
Out[73]:
100

3.4.3 函数定义

In [74]:
x=[1,3,6,4,9,7,5,8,2]; x 
def xbar(x): 
    n=len(x) 
    xm=sum(x)/n 
    return(xm) 
xbar(x)
Out[74]:
[1, 3, 6, 4, 9, 7, 5, 8, 2]
Out[74]:
5.0
In [75]:
np.mean(x) #Python已内建这些函数命令,可直接使用
Out[75]:
5.0

3.4.4 面向对象

In [76]:
X=np.array([1,3,6,4,9,7,5,8,2]);X #列表数组
def SS1(x):                    #计算X的离均差平方和函数
    n=len(x) 
    ss=sum(x**2)-sum(x)**2/n 
    return(ss) 
SS1(X) #SS1(BSdata.身高)
Out[76]:
array([1, 3, 6, 4, 9, 7, 5, 8, 2])
Out[76]:
60.0
In [77]:
 def SS2(x): #返回多个值
        n=len(x) 
        xm=sum(x)/n 
        ss=sum(x**2)-sum(x)**2/n 
        return[x**2,n,xm,ss]  #return(x**2,n,xm,ss) 
SS2(X)  #SS2(BSdata.身高) 
Out[77]:
[array([ 1,  9, 36, 16, 81, 49, 25, 64,  4], dtype=int32), 9, 5.0, 60.0]
In [78]:
SS2(X)[0] #取第 1 个对象 
SS2(X)[1] #取第 2 个对象 
SS2(X)[2] #取第 3 个对象 
SS2(X)[3] #取第 4 个对象 
Out[78]:
array([ 1,  9, 36, 16, 81, 49, 25, 64,  4], dtype=int32)
Out[78]:
9
Out[78]:
5.0
Out[78]:
60.0
In [79]:
#可以使用 type 函数来查看数据或对象的类型
type(SS2(X)) 
type(SS2(X)[3]) 
Out[79]:
list
Out[79]:
numpy.float64