这里写自定义目录标题
简介
这是两个在科学运算中最为重要的两个模块
应用:数据分析、机器学习、深度学习
优点:
- 运算速度快:Numpy和Pandas都是采用C语言编写,Pandas又是基于Numpy,是Numpy的升级版
- 消耗资源少:采用的是矩阵运算,会比Python自带的字典或者列表快
安装
pip3 install numpy
pip3 install pandas
下载提速加 -i https://pypi.tuna.tsinghua.edu.cn/simple
Numpy
numpy的几种属性
ndim维度、shape行数和列数、size元素个数
>>> import numpy as np
>>> array=np.array([[1,2,3],[4,5,6]])
>>> print(array)
[[1 2 3]
[4 5 6]]
>>> print('number of ndim:',array.ndim)
number of ndim: 2
>>> print('number of shape:',array.shape)
number of shape: (2, 3)
>>> print('size:',array.size)
size: 6
关键字
- array创建数组
- atype指定数据类型
a = np.array([1,2.23,3],dtype=np.float) - zeros创建数据全为0
B=np.zeros((3,4)) - ones创建数据全为1
C=np.ones((3,4)) - empty创建数据接近0
C=np.empty((3,4)) - arrange按指定范围创建数据
D=np.arange(10,20,4)
起始、终止、步长 - linspace创建线段
F = np.linspace(1,10,20)
开始断、结束段、分割的数量,分割成20端 - reshape改变数据的形状
E=np.arange(12).reshape((3,4))
基本运算
-
矩阵运算:加、减、乘(,对应元素相乘)、对每个元素平方(**,注意是两个)
-
数学函数:sin、cos等
-
逻辑运算
-
矩阵相乘(dot,矩阵乘法)
写法 E=np.dot(A,C)或者E=A.dot© -
矩阵元素相关 sum()、min()、max()
需要按行或者列进行的话要对axis进行赋值,sxis=0以列为查找单位,sxis=1以行为查找单位
print(‘sum=’,np.sum(A,axis=1))
print(‘min=’,np.min(A,axis=0)) -
求矩阵的最大和最小索引argmin()和argmax()
-
求矩阵元素的平均值 mean()、average()
-
中位数median()
-
分别对前面的值累加cumsum()
-
累差运算diff(),计算每一行中后一项与前一项的差
-
nonzero(),将所有非零元素的行与列坐标分隔开,重构成两个分别关于行和列的矩阵
-
sort()排序,仅针对每一行
-
转置 np.transport(A)或者A.T
-
clip(),比较替换,clip(A,5,9) 所有小于5的替换为5,大于9的替换为9
索引
类似于数组
一维索引
二维索引
两种表达
print(A[0][2])或者print(A[0,2])
可以对一定范围内的元素进行切片操作
>>> print(A[0,1:4])
[4 5 6]
逐行打印
>>> for row in A:
... print(row)
...
逐列打印
>>> for column in A.T:
... print(column)
...
将多维矩阵展开为一行的数列 flatten
>>> print(A.flatten())
[ 3 4 5 6 7 8 9 10 11 12 13 14]
打印矩阵中的每一个元素
>>> for item in A.flat:
... print(item)
array合并
- np.vstack()
上下合并
>>> import numpy as np
>>> A = np.array([1,1,1])
>>> B = np.array([2,3,4])
>>> print(np.vstack((A,B)))
[[1 1 1]
[2 3 4]]
- np.hstack()
左右合并
>>> D = np.hstack((A,B))
>>> print(D)
[1 1 1 2 3 4]
>>> print(A.shape,D.shape)
(3,) (6,)
- np.newaxis()
将不是矩阵属性的序列进行转置
>>> print(A[np.newaxis,:])
[[1 1 1]]
>>> print(A[:,np.newaxis])
[[1]
[1]
[1]]
>>> print(A[:,np.newaxis].shape)
(3, 1)
array分割
- 纵向分割
print(np.split(A,4,axis=1))
注意分割的份数必须为列数的因子 - 横向分割
print(np.split(A,3,axis=0))
分割的份数要求同上 - 不等量分割
print(np.array_split(A,3,axis=1))
纵分割vsplit和横分割hsplit与上面的分割方式相同
Pandas
与numpy的不同
如果用Python的列表和字典来做比较,numpy是列表的形式,没有数值标签,而Pandas则是字典的形式。Pandas基于Numpy构建的
两个重要的数据结构:Series和DataFrame
Series
s=pd.Series([1,3,6,np.nan,44,1])
>>> print(s)
0 1.0
1 3.0
2 6.0
3 NaN
4 44.0
5 1.0
dtype: float64
表现形式:索引在左,值在右,没有指定索引则会自动生成0-N-1的索引
DataFrame
DataFrame是一个表格型的数据结构,包含一组有序的列,每列可以是不同的值的类型(数值,字符串,布尔值等)。既有行索引也有列索引,可以被看做由Series组成的大字典
>>> dates = pd.date_range('20160101',periods=6)
>>> df=pd.DataFrame(np.random.randn(6,4),index=dates,columns=['a','b','c','d'])
>>> print(df)
a b c d
2016-01-01 0.276576 -0.304555 0.093795 -1.810363
2016-01-02 1.466877 -0.691476 0.324591 1.140674
2016-01-03 -0.008028 -1.158561 -0.564495 0.392396
2016-01-04 0.745454 -0.859809 -0.714744 -0.918373
2016-01-05 -0.074341 -1.443231 -1.691037 -1.509217
2016-01-06 -0.379918 -1.160493 -0.283449 -0.780260
>>>
挑选b的元素
>>> print(df['b'])
2016-01-01 -0.304555
2016-01-02 -0.691476
2016-01-03 -1.158561
2016-01-04 -0.859809
2016-01-05 -1.443231
2016-01-06 -1.160493
Freq: D, Name: b, dtype: float64
创建没有给定行标签和列标签的数据
>>> df1=pd.DataFrame(np.arange(12).reshape((3,4)))
>>> print(df1)
0 1 2 3
0 0 1 2 3
1 4 5 6 7
2 8 9 10 11
一些创建方式
>>> df2=pd.DataFrame({'A':1.,
... 'B':pd.Timestamp('20190717'),
... 'C':pd.Series(1,index=list(range(4)),dtype='float32'),
... 'D':np.array([3]*4,dtype='int32'),
... 'E':pd.Categorical(["test","train","test","train"]),
... 'F':'foo'})
>>> print(df2)
A B C D E F
0 1.0 2019-07-17 1.0 3 test foo
1 1.0 2019-07-17 1.0 3 train foo
2 1.0 2019-07-17 1.0 3 test foo
3 1.0 2019-07-17 1.0 3 train foo
这样可以对每一列的数据进行特殊对待,如果要查看数据中的类型,可以使用dtype
>>> print(df2.dtypes)
A float64
B datetime64[ns]
C float32
D int32
E category
F object
dtype: object
查看对应的序列号
>>> print(df2.A)
0 1.0
1 1.0
2 1.0
3 1.0
查看每种数据的名称
>>> print(df2.columns)
Index(['A', 'B', 'C', 'D', 'E', 'F'], dtype='object')
只查看df2的所有的值
>>> print(df2.values)
[[1.0 Timestamp('2019-07-17 00:00:00') 1.0 3 'test' 'foo']
[1.0 Timestamp('2019-07-17 00:00:00') 1.0 3 'train' 'foo']
[1.0 Timestamp('2019-07-17 00:00:00') 1.0 3 'test' 'foo']
[1.0 Timestamp('2019-07-17 00:00:00') 1.0 3 'train' 'foo']]
查看数据的总结
>>> print(df2.describe())
A C D
count 4.0 4.0 4.0
mean 1.0 1.0 3.0
std 0.0 0.0 0.0
min 1.0 1.0 3.0
25% 1.0 1.0 3.0
50% 1.0 1.0 3.0
75% 1.0 1.0 3.0
max 1.0 1.0 3.0
翻转数据直接使用transpose
对数据的index进行排序并输出
>>> print(df2.sort_index(axis=0,ascending=False))
A B C D E F
3 1.0 2019-07-17 1.0 3 train foo
2 1.0 2019-07-17 1.0 3 test foo
1 1.0 2019-07-17 1.0 3 train foo
0 1.0 2019-07-17 1.0 3 test foo
对值进行排序
>>> print(df.sort_values(by='a'))
a b c d
2016-01-06 -0.379918 -1.160493 -0.283449 -0.780260
2016-01-05 -0.074341 -1.443231 -1.691037 -1.509217
2016-01-03 -0.008028 -1.158561 -0.564495 0.392396
2016-01-01 0.276576 -0.304555 0.093795 -1.810363
2016-01-04 0.745454 -0.859809 -0.714744 -0.918373
2016-01-02 1.466877 -0.691476 0.324591 1.140674
Pandas选择数据
两种方法
df[A]或者df.A都代表取出index为A的那一列
可以使用:来选取一个范围内的行(这个可以是行序号也可以是行的标号)
>>> print(df[0:2])
A B C D
2016-01-01 0 1 2 3
2016-01-02 4 5 6 7
或者
>>> print(df['20160101':'20160102'])
A B C D
2016-01-01 0 1 2 3
2016-01-02 4 5 6 7
- 根据标签loc(使用标签名)
loc方法可以用来选择某行或者所有行(使用:)的某列或者所有列(使用:)
>>> print(df.loc[:,'A'])
2016-01-01 0
2016-01-02 4
2016-01-03 8
2016-01-04 12
2016-01-05 16
2016-01-06 20
Freq: D, Name: A, dtype: int64
>>> print(df.loc['20160101':'20160104','A'])
2016-01-01 0
2016-01-02 4
2016-01-03 8
2016-01-04 12
>>> print(df.loc['20160101':'20160104','A':'C'])
A B C
2016-01-01 0 1 2
2016-01-02 4 5 6
2016-01-03 8 9 10
2016-01-04 12 13 14
- 根据序列iloc(使用位置)
作用同上
>>> print(df.iloc[0:3,:])
A B C D
2016-01-01 0 1 2 3
2016-01-02 4 5 6 7
2016-01-03 8 9 10 11
>>> print(df.iloc[:,1])
2016-01-01 1
2016-01-02 5
2016-01-03 9
2016-01-04 13
2016-01-05 17
2016-01-06 21
Freq: D, Name: B, dtype: int64
- 根据混合的这两种ix
作用同上,可以使用位置或者标签名都可以 - 根据判断的筛选
>>> print(df[df.A>8])
A B C D
2016-01-04 12 13 14 15
2016-01-05 16 17 18 19
2016-01-06 20 21 22 23
>>> print(df.A>8)
2016-01-01 False
2016-01-02 False
2016-01-03 False
2016-01-04 True
2016-01-05 True
2016-01-06 True
Freq: D, Name: A, dtype: bool
设置数据
- 根据位置设置loc和iloc
差别在于iloc使用位置
loc使用标签名
>>> df.iloc[3,2]=1111
>>> print(df)
A B C D
2016-01-01 0 1 2 3
2016-01-02 1314 5 6 7
2016-01-03 8 9 10 11
2016-01-04 12 13 1111 15
2016-01-05 16 17 18 19
2016-01-06 20 21 22 23
>>> df.loc['20160102','A']=1314
>>> print(df)
A B C D
2016-01-01 0 1 2 3
2016-01-02 1314 5 6 7
2016-01-03 8 9 10 11
2016-01-04 12 13 14 15
2016-01-05 16 17 18 19
2016-01-06 20 21 22 23
- 根据条件设置
>>> df.B[df.B>4]=0
>>> print(df)
A B C D
2016-01-01 0 1 2 3
2016-01-02 1314 0 6 7
2016-01-03 8 0 10 11
2016-01-04 12 0 1111 15
2016-01-05 16 0 18 19
2016-01-06 20 0 22 23
- 按行或按列设置
>>> df['F']=np.nan
>>> print(df)
A B C D F
2016-01-01 0 1 2 3 NaN
2016-01-02 1314 0 6 7 NaN
2016-01-03 8 0 10 11 NaN
2016-01-04 12 0 1111 15 NaN
2016-01-05 16 0 18 19 NaN
2016-01-06 20 0 22 23 NaN
- 添加数据
>>> df['E']=pd.Series([1,2,3,4,5,6],index=pd.date_range('20160101',periods=6))
>>> print(df)
A B C D F G E
2016-01-01 0 1 2 3 NaN NaN 1
2016-01-02 1314 0 6 7 NaN NaN 2
2016-01-03 8 0 10 11 NaN NaN 3
2016-01-04 12 0 1111 15 NaN NaN 4
2016-01-05 16 0 18 19 NaN NaN 5
2016-01-06 20 0 22 23 NaN NaN 6
处理丢失数据
- pd.dropna()
直接去掉有NaN的行或列
>>> df.dropna(
... axis=0,
... how='any'
... )
A B C D
2016-01-03 8 9.0 10.0 11
2016-01-04 12 13.0 14.0 15
2016-01-05 16 17.0 18.0 19
2016-01-06 20 21.0 22.0 23
axis为0行,1为列
- pd.fillna()
将NaN的值用其他的值替代
>>> df.fillna(value=1111)
A B C D
2016-01-01 0 1111.0 2.0 3
2016-01-02 4 5.0 1111.0 7
2016-01-03 8 9.0 10.0 11
2016-01-04 12 13.0 14.0 15
2016-01-05 16 17.0 18.0 19
2016-01-06 20 21.0 22.0 23
- pd.isnull()
判断是否有缺失数据
>>> df.isnull()
A B C D
2016-01-01 False True False False
2016-01-02 False False True False
2016-01-03 False False False False
2016-01-04 False False False False
2016-01-05 False False False False
2016-01-06 False False False False
数据的导入导出
使用pd.read_csv()来导入.cxv后缀的文件
>>> data=pd.read_csv('/home/gyy/work/code/python/student.csv')
>>> print(data)
Student ID name age gender
0 1100 Kelly 22 Female
1 1101 Clo 21 Female
2 1102 Tilly 22 Female
3 1103 Tony 24 Male
4 1104 David 20 Male
5 1105 Catty 22 Female
6 1106 M 3 Female
7 1107 N 43 Male
8 1108 A 13 Male
9 1109 S 12 Male
10 1110 David 33 Male
11 1111 Dw 3 Female
12 1112 Q 23 Male
13 1113 W 21 Female
将文件存取成pickle
>>> data.to_pickle('student.pickle')
以后就可以对pickle进行处理
pickle更节约存储空间
合并 concat
- axis(合并方向)
默认axis=0,纵向合并,1的话是横向合并
>>> df1=pd.DataFrame(np.ones((3,4))*0,columns=['a','b','c','d'])
>>> df2=pd.DataFrame(np.ones((3,4))*1,columns=['a','b','c','d'])
>>> df3=pd.DataFrame(np.ones((3,4))*2,columns=['a','b','c','d'])
>>> res=pd.concat([df1,df2,df3],axis=0)
>>> print(res)
a b c d
0 0.0 0.0 0.0 0.0
1 0.0 0.0 0.0 0.0
2 0.0 0.0 0.0 0.0
0 1.0 1.0 1.0 1.0
1 1.0 1.0 1.0 1.0
2 1.0 1.0 1.0 1.0
0 2.0 2.0 2.0 2.0
1 2.0 2.0 2.0 2.0
2 2.0 2.0 2.0 2.0
- 处理index
>>> res=pd.concat([df1,df2,df3],axis=0,ignore_index=True)
>>> print(res)
a b c d
0 0.0 0.0 0.0 0.0
1 0.0 0.0 0.0 0.0
2 0.0 0.0 0.0 0.0
3 1.0 1.0 1.0 1.0
4 1.0 1.0 1.0 1.0
5 1.0 1.0 1.0 1.0
6 2.0 2.0 2.0 2.0
7 2.0 2.0 2.0 2.0
8 2.0 2.0 2.0 2.0
- join(合并方式)
>>> df1 = pd.DataFrame(np.ones((3,4))*0, columns=['a','b','c','d'], index=[1,2,3])
>>> df2 = pd.DataFrame(np.ones((3,4))*1, columns=['b','c','d','e'], index=[2,3,4])
>>> res = pd.concat([df1, df2], axis=0, join='outer')
>>> print(res)
a b c d e
1 0.0 0.0 0.0 0.0 NaN
2 0.0 0.0 0.0 0.0 NaN
3 0.0 0.0 0.0 0.0 NaN
2 NaN 1.0 1.0 1.0 1.0
3 NaN 1.0 1.0 1.0 1.0
4 NaN 1.0 1.0 1.0 1.0
会选择相同的项进行合并,如果有没有值的地方会写NaN
只合并相同的column抛弃其他的
>>> res = pd.concat([df1, df2], axis=0, join='inner')
>>> print(res)
b c d
1 0.0 0.0 0.0
2 0.0 0.0 0.0
3 0.0 0.0 0.0
2 1.0 1.0 1.0
3 1.0 1.0 1.0
4 1.0 1.0 1.0
- append(追加数据)
与上面合并的用法类似,只能纵向合并