写在前面
在用python做一些ML和DL的工作前,先看莫烦大佬的视频学习一下numpy和pandas这两个数据处理包,学习中记了一些笔记,便于自己日后查阅,同时发布到知乎希望能够帮助到其他小伙伴!
视频如下:Numpy & Pandas (莫烦 Python 数据处理教程)_哔哩哔哩 (゜-゜)つロ 干杯~-bilibiliwww.bilibili.com
一、numpy & pandas 有什么用
ML、DL的基础,用于数据分析。
计算速度更快,比py自带的数据结构快很多,因为numpy和pandas是用C写的,panda是numpy的升级版。
矩阵计算速度快。
二、numpy & pandas 安装
pip install numpy
pip install pandas
三、numpy 基本属性
import numpy as np
array = np.array([[1,2,3],
[2,3,4]]) #创建矩阵
print(array) #打印矩阵
print('number of dim:', array.ndim) #矩阵维度
print('shape:', array.shape) #矩阵形状(n*m) n行m列
print('size:', array.size) #矩阵元素数量
四、numpy 创建 array
import numpy as np
a = np.array([2,23,4], dtype=np.int) #定义数据的格式为int, 还有int64、int32、float64、float32
print(a.dtype) #打印矩阵a中的元素数据类型
b = np.array([[2,23,4],
[2,32,4]]) #定义2*3的矩阵
c = np.zeros((3,4)) # 定义全部为0的矩阵,参数为shape
print(c)
d = np.ones((3,4), dtype=np.int16) # 定义全部为1的矩阵,参数为shape
print(d)
e = np.empty((3,4)) # 定义全部为无穷小的矩阵,参数为shape
print(e)
f = np.arange(10, 20, 2) # 从10到20,不包含20,步长为2
print(f)
g = np.arange(12).reshape((3,4)) # 从0到12,不包含12,步长为1,重新定义大小为3*4
print(g)
h = np.linspace(1, 10, 20).reshape((4,5)) # 数列,从1到10,分为20段,最后一个是10..
#也可以更改shape
print(h)
五、numpy 基础运算1
#数列操作
import numpy as np
a = np.array([10, 20, 30, 40])
b = np.arange(4) #0,1,2,3
print(a, b) #[10 20 30 40] [0 1 2 3]
c = a-b
print(c) #[10 19 28 37]
c = a+b
print(c) #[10 21 32 43]
c = b**2 #b的平方
print(c) #[0 1 4 9]
c = 10*np.sin(a) #对a的每一个元素求sin,然后乘以10 # tan、cos类似
print(c) #[-5.44021111 9.12945251 -9.88031624 7.4511316 ]
print(b) #[0 1 2 3]
print(b<3) #[ True True True False] #判断,同理可以用其他判断符
#矩阵操作
import numpy as np
a = np.array([[1,1],
[0,1]])
b = np.arange(4).reshape((2,2)) #0,1,2,3
print(a)
print(b)
c = a*b #元素逐个相乘
c_dot = np.dot(a, b) #矩阵乘法
print(c)
print(c_dot)
c_dot_2 = a.dot(b) # 与c_dot = np.dot(a, b)相同
a = np.random.random((2, 4)) #随机矩阵,0-1的均匀分布
print(a)
print(np.sum(a)) #求和
print(np.min(a)) #最小值
print(np.max(a)) #最大值
print(np.sum(a, axis=1)) #按照每一行或每一列计算,0表示对列操作,1表示对行操作
#min 和 max 类似
六、numpy 基础运算2
import numpy as np
a = np.arange(14, 2, -1).reshape((3, 4))
print(a)
print(np.argmin(a)) #输出最小值的index
print(np.argmax(a)) #输出最大值的index
print(np.mean(a)) #平均值 也可以 a.meanin
print(np.average(a)) #同mean, 但不可以a.average
print(np.median(a)) #中位数
print(np.cumsum(a)) #逐位相加 输出n*m个元素 一行,前缀和
print(np.diff(a)) #累差,每两个之间的差, n*(m-1)
print(np.nonzero(a)) #输出非零元素的行和列 index,行为一个array,列为一个array
print(np.sort(a)) #默认按照每一行排序,行间不排序
print(np.transpose(a)) #转置
print(a.T) #转置
print((a.T).dot(a)) # aT * a
print(np.clip(a, 5, 9)) #所有大于9的数变成了9,所有小于5的数变成了5,中间的数不变
其中很多计算函数,如mean、median 都可以在参数中指定axis,0表示每一列计算,1表示每一行计算。
七、numpy 索引
import numpy as np
a = np.arange(3, 15)
print(a)
print(a[3]) #输出3号元素
a = a.reshape((3, 4))
print(a)
print(a[2]) #输出2号行
print(a[1][1]) #输出第一行第一列
print(a[1,1]) #等价于上一行
print(a[1,:]) #:代表所有数
print(a[1,1:3]) #第1行的 从第1列到第3列
print()
for row in a:
print(row) #循环输出每一行
for col in a.T:
print(col) #循环输出每一列
for item in a.flat: #转换成一行 #a.flatten() 返回一个一行的序列
print(item) #循环输出每一个item
八、numpy array合并
import numpy as np
a = np.array([1, 1, 1])
b = np.array([2, 2, 2])
c = np.vstack((a, b)) #vertical stack 上下合并
print(c)
print(a.shape, c.shape)
d = np.hstack((a, b)) #horizontal stack 左右合并
print(d)
print(a.shape, d.shape)
print(a[np.newaxis, :]) #为行新加一个维度 变成了1*3
print(a[:, np.newaxis]) #为列新加一个维度 变成了3*1
a = a[:, np.newaxis]
b = b[:, np.newaxis]
print(np.hstack((a,b))) #纵向合并,变成3*2
c = np.concatenate((a,b,b,a), axis=1) #合并,0是上下合并,1是左右合并
print(c)由于我之前一直使用的MATLAB,所以python的这一部分有些不能理解,为什么一维向量转置后还是本身?
经过测试,我个人理解numpy的工作很看重维度,一维下转置还是一维,所以还是自己本身。使用newaxis扩展维度后,变成了二维,才可以做真正的转置。
在一维下进行合并,也只能横向扩展,不能跨越维度
九、numpy的array分割
import numpy as np
a = np.arange(12).reshape((3,4))
print(a)
print(np.split(a,3,axis=0)) #0为按行切割, 1为按列切割
#不能进行不等的分割 split(a,2,axis=0)
print(np.array_split(a,3,axis=1)) #可以不等分割
print(np.vsplit(a,3)) #纵向分割 相当于axis=0
print(np.hsplit(a,2)) #横向分割 相当于axis=1
十、numpy的 copy & deep copy
import numpy as np
a = np.arange(4)
print(a)
b = a
c = a
d = b
a[0] = 11
print(a)
print(b) #与a相同,所以直接赋值是浅拷贝
print(c is a) #True
b = a.copy() # deep copy
a[0] = 88
print(a)
print(b)
十一、pandas 基本介绍
如果说numpy像列表,那pandas像字典。
pandas可以为行和列自定义名字,在ML中,可以将其命名为feature的名字
import numpy as np
import pandas as pd
s = pd.Series([1,3,6,np.nan,44,1]) #有序号的列表
print(s)
dates = pd.date_range('20160101', periods=6) #日期序列
print(dates)
df = pd.DataFrame(np.random.randn(6,4),index = dates, columns=['a', 'b', 'c', 'd'])
#行是index columns 是列
print(df)
df1 = pd.DataFrame(np.arange(12).reshape((3,4)))
print(df1) #行和列的名字默认是 从0开始的序号
df2 = pd.DataFrame({'A':1.,'B':pd.Timestamp('20130102'),
'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'})
#可以传入一个字典,其中A B C D E F 为列名
print(df2)
print(df2.dtypes) #查看每一列的数据类型
print(df2.index) #每一行的名字
print(df2.columns) # 每一列的名字
print(df2.values) #每一个值
print(df2.describe()) #输出每一列的 count、mean、std、min、25%、50%、75%、max
print(df2.T) #转置
print(df2.sort_index(axis=1,ascending=False))
#axis为1是按列排序,0是按行排序,ascending=false:倒序排序
print(df2.sort_index(axis=0,ascending=False))
print(df2.sort_values(by='E')) #对其中的值排序,根据某一列
十二、pandas 选择数据
import numpy as np
import pandas as pd
dates = pd.date_range('20130101', periods=6)
df = pd.DataFrame(np.arange(24).reshape((6,4)), index=dates, columns=['A','B','C','D'])
print(df)
print(df['A'], df.A) #打印第A列
print(df[0:3], df['20130102':'20130104']) #打印第0-3行,然后打印第02-04行
#select by label:loc
print(df.loc['20130102']) #按照标签选择
print(df.loc[:,['A','B']]) #所有行的A列和B列
print(df.loc['20130102',['A','B']]) #选择某些数据
#select by position:iloc
print(df.iloc[3, 1]) #第三行第一列
print(df.iloc[3:5, 1:3]) #切片
print(df.iloc[[1,3,5], 1:3]) #不连续的筛选
#mixed selection:ix
#print(df.ix[:3,['A','C']]) #报错,python3已经弃用ix
#Boolean indexing
print(df[df.A > 8]) #筛选出A列中大于8的行ix已经弃用,会报错
十三、pandas 设置值
import numpy as np
import pandas as pd
dates = pd.date_range('20130101', periods=6)
df = pd.DataFrame(np.arange(24).reshape((6,4)), index=dates, columns=['A','B','C','D'])
print(df)
df.iloc[2,2] = 1111 #按照index修改值
df.loc['20130101','B'] = 2222
df[df.A>4] = 0 #把第A列大于4的行都改为0,修改所有列的
print(df)
df = pd.DataFrame(np.arange(24).reshape((6,4)), index=dates, columns=['A','B','C','D'])
df.A[df.A>4] = 0 #只修改第A列的
print(df)
df['F'] = np.nan #增加一列 nan
df['E'] = pd.Series([1,2,3,4,5,6], index=dates) #增加一列,序列
print(df)
十四、pandas 处理丢失数据
import numpy as np
import pandas as pd
dates = pd.date_range('20130101', periods=6)
df = pd.DataFrame(np.arange(24).reshape((6,4)), index=dates, columns=['A','B','C','D'])
df.iloc[0,1] = np.nan
df.iloc[1,2] = np.nan #创造丢失数据
print(df)
#drop
print(df.dropna(axis=0, how='any')) #丢掉数据,axis=0 丢掉这一行
#how={'any','all'} any: 有一个nan 就丢掉这一行, all:全部为nan才丢掉, 默认any
print(df.dropna(axis=1, how='any')) #丢掉数据,axis=1 丢掉这一列
#fill
print(df.fillna(value=0)) #将nan填充为0
print(df.isnull()) #对每个value判断是否为nan 返回beal 矩阵
print(np.any(df.isnull())==True) #只要有一个丢失的数据,就返回true
十五、pandas 导入导出数据
import numpy as np
import pandas as pd
#读入
data = pd.read_csv('student.csv') #读取csv表格
print(data) #会在每一行自动加一个索引 0-n
#存储
data.to_pickle('student.pickle') #写出为pickle文件
读为 read_#
写入为 to_#
其中#都可以用如下字符代替:csv
excel
hdf
sql
json
msgpack
html
gbq
stata
sas
clipboard
pickle
十六、pandas 合并 concat
import numpy as np
import pandas as pd
# concatenating
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'])
print(df1)
print(df2)
print(df3)
res = pd.concat([df1, df2, df3], axis=0) #合并, 0为纵向合并,1为横向合并
#此方法行的index重复了
print(res)
res = pd.concat([df1, df2, df3], axis=0, ignore_index=True) #index重新排序
print(res)
#join ['inner', 'outer']
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])
print(df1)
print(df2)
res = pd.concat([df1, df2]) #默认为outer模式合并,把没有的列用nan填充
print(res)
res = pd.concat([df1, df2], join='inner') #inner为只合并共有的列
print(res)
#res = pd.concat([df1,df2], axis=1, join_axes=[df1.index])
#横向合并,由于行的index不一样,使用join_axes使得其按照df1的index进行合并,df2中缺失值用nan填充
#由于join_axes已被弃用,会报错
#append
res = df1.append([df2,df3], ignore_index=True)
#在其后追加
print(res)
s1 = pd.Series([1,2,3,4],index=['a','b','c','d'])
res = df1.append(s1, ignore_index=True)
print(res)join_axes 已被弃用
其中 s1 = pd.Series([1,2,3,4],index=['a','b','c','d'])
对列标签用了index,如果使用columns会报错
与第八讲补充内容一致,由于此向量为一维,所以不存在列的概念,故只能使用index
十七、pandas 合并 merge
import numpy as np
import pandas as pd
#merging two df by key/keys.(may be used in database)
#simple example
left = pd.DataFrame({'key':['K0', 'K1', 'K2', 'K3'],
'A':['A0', 'A1', 'A2', 'A3'],
'B':['B0', 'B1', 'B2', 'B3']})
right = pd.DataFrame({'key':['K0', 'K1', 'K2', 'K3'],
'C':['C0', 'C1', 'C2', 'C3'],
'D':['D0', 'D1', 'D2', 'D3']})
print(left)
print(right)
res = pd.merge(left, right, on='key') #基于key这一列合并
print(res)
#consider two keys
left = pd.DataFrame({'key1':['K0', 'K0', 'K1', 'K2'],
'key2':['K0', 'K1', 'K0', 'K1'],
'A':['A0', 'A1', 'A2', 'A3'],
'B':['B0', 'B1', 'B2', 'B3']})
right = pd.DataFrame({'key1':['K0', 'K1', 'K1', 'K2'],
'key2':['K0', 'K0', 'K0', 'K0'],
'C':['C0', 'C1', 'C2', 'C3'],
'D':['D0', 'D1', 'D2', 'D3']})
print(left)
print(right)
res = pd.merge(left, right, on=['key1','key2']) #默认只合并相同的key (how='inner')
print(res)
#how = ['left', 'right', 'outer', 'inner']
res = pd.merge(left, right, on=['key1','key2'], how='outer') #全部合并,没有的用nan填充
print(res)
res = pd.merge(left, right, on=['key1','key2'], how='right') #以right的key为基准进行填充
print(res)
#indicator
df1 = pd.DataFrame({'col1':[0,1], 'col_left':['a', 'b']})
df2 = pd.DataFrame({'col1':[1,2,2], 'col_right':[2,2,2]})
print(df1)
print(df2)
res = pd.merge(df1, df2, on='col1', how='outer', indicator=True) #指示出如何合并的 默认在_merge列
print(res)
res = pd.merge(df1, df2, on='col1', how='outer', indicator='indicator_column')#更改了合并方式的列名
print(res)
#merged by index
left = pd.DataFrame({'A':['A0', 'A1', 'A2'],
'B':['B0', 'B1', 'B2']},
index=['K0', 'K1', 'K2'])
right = pd.DataFrame({'C':['C0', 'C2', 'C3'],
'D':['D0', 'D2', 'D3']},
index=['K0', 'K2', 'K3'])
print(left)
print(right)
# left_index and right_index
res = pd.merge(left, right, left_index=True, right_index=True, how='outer')
#left_index 和 right_index 默认false, 表示考虑index来合并
print(res)
#handle overlapping
boys = pd.DataFrame({'k':['K0','K1','K2'], 'age':[1,2,3]})
girls = pd.DataFrame({'k':['K0','K0','K3'], 'age':[4,5,6]})
print(boys)
print(girls)
res = pd.merge(boys, girls, on='k', how='inner', suffixes=['_boy', '_girl'])
#为left 和 right 相同的列增加前缀,为不同的列
print(res)
十八、pandas plot 画图
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
#plot data
#Series
data = pd.Series(np.random.randn(1000), index=np.arange(1000))
data = data.cumsum() #累加和
print(data)
data.plot() #画图
plt.show()
#DataFrame
data = pd.DataFrame(np.random.randn(1000,4),
index=np.arange(1000),
columns=list("ABCD"))
data = data.cumsum()
print(data.head()) #打印前5个
data.plot()
plt.show()
#plot methods:
#bar, hist, box, kde, area, scatter, hexbin, pie
ax = data.plot.scatter(x='A', y='B', color='DarkBlue', label='Claass 1') #分布点
data.plot.scatter(x='A', y='C', color='DarkGreen', label='Class 2', ax=ax)
#一张图画两组数据
plt.show()