提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档
numpy@pandas
一、作用
基于c,加速数据计算
二、numpy
- 创建数组
# 导入并取别名
import numpy as np
# np.array函数产生ndarray对象
array = np.array([[1, 2, 3], [2, 3, 4]])
# dtype数据类型
a = np.array([1, 2, 3], dtype=np.int64)
# ndim数组维数
print(a, a.ndim, a.shape, a.size, a.dtype)
- 一维数组运算
b = np.array([10, 20, 30, 40])
# arange产生从0开始的一维数组
c = np.arange(4)
d = b ** 2 + np.tan(c)
print(d)
- 矩阵运算
a = np.array([[1, 1],
[0, 1]])
# arange产生从0开始的一维数组,reshape变成矩阵
b = np.arange(4).reshape((2, 2))
# 矩阵乘法有两种:
# 1.逐个相乘
c = a * b
# 2.矩阵乘法
c_dot = np.dot(a, b)
# a是ndarray,可直接调用其dot函数,和上面一个意思,写法不同
c_dot2 = a.dot(b)
# random.random 随机生成3行4列0.0-1.0浮点数
a = np.random.random((3, 4))
print(a)
# 从每列中取出最大值
print(np.max(a, axis=1))
4.numpy索引、平均值、中位数、累差
A = np.arange(2, 14).reshape((3, 4))
# 计算最小值的索引
print(np.argmin(A))
# 计算最大值的索引
print(np.argmax(A))
# 计算平均值,axis:1是对行平均,0是列
print(np.mean(A))
print(A.mean())
# 计算中位数
print(np.median(A))
# 累加:前一位依次加到后一位
print(np.cumsum(A))
# 累差:依次计算相邻数的差值
print(np.diff(A))
# nonzero输出非0数的索引(包含一个行索引和列索引)
5.对矩阵操作
# arange从小到大 默认步长1,从大到小需设置步长为负数
A = np.arange(14, 2, -1).reshape((3, 4))
# sort是对各行排序
print(np.sort(A))
# 矩阵转置
print(np.transpose(A))
print(A.T)
# 截断:类似阈值 滤波,小于最小值的数变成最小值,大于最大值的数变成最大值
print(np.clip(A, 4, 9))
切片,按行、列打印,降维
# 矩阵索引切片
A = np.arange(3,15).reshape((3, 4))
# (:)切片数学表示[,)
print(A[1, 1:3])
# 可使用for循环打印出每一行
for row in A:
print(row)
# 将A转置可打印出列
for column in A.T:
print(column)
# flatten将矩阵降维成一维数组
print(A.flatten())
for item in A.flat:
print(item)
- array合并
A = np.array([1,1,1])
B = np.array([2, 2, 2])
# vstack上下合并
C = np.vstack((A, B))
# hstack左右合并,矩阵拼接
D = np.hstack((A, B))
升维、列表变矩阵
# 一维向量变矩阵,横向数列变纵向
print(A.reshape(3,1))
# mat.T可以一维变矩阵,array不行
# tip:处理矩阵用matrix,数组用
F = np.mat([1,1,1])
# np.newaxis增加新维度,放列上可将一维数组转化成矩阵
print(A[:, np.newaxis])
B = np.array([2, 2, 2])[:, np.newaxis]
矩阵合并
# array数组是(3,0),使用[:, np.newaxis]在列上增加维度,变成矩阵,才能用concatena
A = np.array([1,1,1])[:, np.newaxis]
B = np.array([2, 2, 2])[:, np.newaxis]
# np.concatenate对多个矩阵横向或纵向合并
G = np.concatenate((A,A,B,B,),axis=0)
矩阵分割
# array分隔,split(),0为上下分割,1为左右分割
A = np.arange(12).reshape((3,4))
# np.split只能平均分割;np.array_split可以进行不等分割,原理类似每次对一个array做对折
print(np.split(A,3,axis=0))
# 纵向分割
print(np.vsplit(A,3))
# 横向分割
print(np.hsplit(A,2))
copy、deep copy
# np中array用=赋值,起引用效果,一个array值改变,所有赋值array都改变(浅拷贝:指向同一地址)
# is 比较对象的地址,==比较对象的值
a = np.array([1,2,3])
b = a
# 深拷贝:赋值但不关联,指向不同地址
c = a.copy()
d = a[:]
# 真正意义上的深拷贝
e = a.__deepcopy__()
三、pandas
pandas不同于numpy的点在于,pandas将数据表格化,有行名、列名,增加对行列操作
查找
- Series以表格形式打印出元素
*s = pd.Series([1,3,6,np.nan,44,1])*
date_range以日期形式打印
dates = pd.date_range('20220815', periods=6)*
DatetimeIndex([‘2022-08-15’, ‘2022-08-16’, ‘2022-08-17’, ‘2022-08-18’,
‘2022-08-19’, ‘2022-08-20’],
dtype=‘datetime64[ns]’, freq=‘D’)
index设置行名称,columns设置列名称,DataFrame中行列名默认从0开始
df = pd.DataFrame(np.random.randn(6,4),index=dates,columns=['a','b','c','d'])
运行结果
a b c d
2022-08-15 0.538968 0.253723 0.202965 0.840419
2022-08-16 -1.816145 -0.838663 0.080068 0.335355
2022-08-17 -2.003523 -0.334556 -0.600103 -0.865847
2022-08-18 0.533522 -0.846731 -0.042258 0.985196
2022-08-19 -1.273009 -0.596692 -0.208470 0.829764
2022-08-20 -1.249748 -0.421765 0.048790 -0.353773
df2 = pd.DataFrame({'A':1.,
'B':pd.Timestamp('20220815'),
'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':'fool'})
运行结果:
A B C D E F
0 1.0 2022-08-15 1.0 3 test fool
1 1.0 2022-08-15 1.0 3 train fool
2 1.0 2022-08-15 1.0 3 test fool
3 1.0 2022-08-15 1.0 3 train fool
df2.dtypes查看数据形式
df2.index查看行名
df2.colums查看列名
df2.values查看所有的值
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
df2.T转置,data不变,行名、列名互换
df2.sort_index(axis= 0, ascending=False)可按行列名大小排序(数据跟着改变),ascending确定升序
df2.sort_values(by=‘E’)按e列数据大小改变行序
当列名是字符串,可直接.列名,打印出该列元素(没法.行名取行,取行用df[切片]来取)
- pands取指定列:
print(df2.A)
print(df2['A']) //效果一样
- pands取指定:
print(df[0:3])
print(df['20220815':'20220820']) //切片中用行号和行名取,效果一样
- 通过标签(行名/列名)选取:.loc
print(df.loc['20220815', ['A', 'B']])
- 通过位置切片选取: .iloc
print(df.iloc[3:5, 1:])
print(df.iloc[[1,3,5], 1:])
混合选取(标签、位置切片结合):.ix ix已经被弃用,用iloc替代
- 布尔索引筛选(可以把符合要求数据对应的整行数据打印)
改值
print(df[(df.A>8)&(df.B<20)])
运行结果:
A B C D
d 12 13 14 15
e 16 17 18 19
如果没有定义标签,不能用loc进行values修改
df.loc['a','B']=222
df..iloc[2,2]= 222
区分
df.A[df.A>4]=0 //只改变A列
A B C D
a 0 1 2 3
b 4 5 6 7
c 0 9 10 11
d 0 13 14 15
e 0 17 18 19
f 0 21 22 23
df[df.A>4]= 0 //符合条件行对应所有元素都变
A B C D
a 0 1 2 3
b 4 5 6 7
c 0 0 0 0
d 0 0 0 0
e 0 0 0 0
f 0 0 0 0
- 加空列
df['F'] = np.nan
把连续values加到固定行上
df['E'] = pd.Series([1,2,3,4,5,6],index = pd.date_range('20130101',periods= 6))
处理空数据
- 删除nan数据对应的行(0)或列(1)
any只要有一个nan就删本行/列,all本行/列全为nan才删
df.dropna(axis = 0,how = 'all') //how = {‘any’,'all'}
- 填充nan数据
df.fillna(value = 0)
判断是否nan
df.isnull() //返回整个表格的判断值
np.any(df.isnull() == True) //判断整个表是否有nan,只返回一个布尔
文件读取保存
# padas以read_**形式读取(格式csv,excel,hdf,sql,json,msgpack,html,gbq,stata,sas,cil[board,pickle)
data =pd.read_csv("E:/我的材料/本科生材料/1731信息登记.csv")
# 以to_**形式保存(格式同上)
data.to_pickle("E:/我的材料/本科生材料/1731信息登记.pickle")
concat合并df表格
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'])
# concat合并df表格,
# axis:0合并行,行数改变;1合并列,列增加。
# ignore_index=true,更正行号
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
表格内连接、外连接
外连接
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,4,5])
# 行列号不一样时,考虑join属性;outer拼接成一大块,没数据的补nan;inner做并集,只保留相交部分
res = pd.concat([df1,df2],join='outer')
运行结果:
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
4 NaN 1.0 1.0 1.0 1.0
5 NaN 1.0 1.0 1.0 1.0
内连接
res = pd.concat([df1,df2],join='inner',ignore_index=True)
运行结果:
b c d
0 0.0 0.0 0.0
1 0.0 0.0 0.0
2 0.0 0.0 0.0
3 1.0 1.0 1.0
4 1.0 1.0 1.0
5 1.0 1.0 1.0
concat的join_index属性已被弃用
使用merge方法替代
# left_index:为True时将左表的索引作为连接键,默认为False
# how:两个数据连接方式,默认为inner,可设置inner、outer、left或right
res = pd.merge(df1,df2,how='left',left_index=True,right_index=True)
concat普适,join用于左右合并,append用于上下合并,ignore_index可用于前面三者进行修饰。
append加一行数据
res= df1.append(df2,ignore_index=True) //加一个表dataframe
s1 = pd.Series([1,2,3,4],index= ['a','b','c','d']) //加一行元素
res = df1.append(s1,ignore_index=True)
merge,on:基于key列(某共有列)进行合并
选择一列合并
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']})
# on选择基于哪一列进行合并
res = pd.merge(left, right, on='key')
选择2个列合并
# innner保留两个表共有的key对应的行,outer把所有都复制下来(空数据补nan)
# left以第一个表的key为底,把表2中被表1包含的key行复制到新表;right同理
res = pd.merge(left, right, on=['key1','key2'],how=inner)
merge的提示属性indicator,显示怎么合并的;默认false不打开;true打开;也可=‘自定义本列名’
res = pd.merge(left, right, on=['key1','key2'],how=inner,indicator=True) //true打开提示合并方式
res = pd.merge(left, right, on=['key1','key2'],how=inner,indicator='indicator_column') //='自定义本列名'
以行号做key进行合并
不需要用on,用left_index=True,right_index=True
res = pd.merge(df1,df2,how='left',left_index=True,right_index=True)
suffixes=[‘_boy’,‘_girl’]把除key列外的列加后缀,来表明本列数据出自哪个表
res = pd.merge(boys,girls,on= 'k',suffixes=['_boy','_girl'],how='outer')
运行结果:
k age_boy age_girl
0 k0 1.0 2.0
1 k0 1.0 5.0
2 k1 2.0 NaN
3 k2 3.0 NaN
4 k3 NaN 3.0
总结
提示:这里对文章进行总结:
例如:以上就是今天要讲的内容,本文仅仅简单介绍了pandas的使用,而pandas提供了大量能使我们快速便捷地处理数据的函数和方法。