目录
1.numpy数据库
1)数组
(1)创建数组
# 导入库 import numpy as np
arr1 = np.array([-9,7,4,3])
np.arange(0,10,1)
np.linspace(1,10,10)
np.logspace(1,5,base=2,num=10)#创建等比数列
#特征
arr1.ndim: 返回int,表示ndarray的维度
arr1.shape: 返回尺寸,几行几列
arr1.size: 返回数组元素的个数 •
arr1.dtype: 返回数组中元素的类型 •
运算: 直接可以在每个元素加减乘除
(2)花式索引
arr2[[1,-1],[0,1]] #获取(1,0),(-1,1) 位置上的元素,(第二行,第一列)和(最后一行,第二列)的元素
arr2[[0,-1]][:,[0,1,3]] # 获取第一行,最后一行,以及第一列,第二列和第四列的元素
(3) 数组形状改变
- • reshape 是返回视图 arr1.reshape(2,6);resize回直接改变自身;这两个函数主要用于改变数组的形状,请注意区别
- • ravel和flatten对数组直接进行一维转换,展平为一维数组 ravel、flatten和reshape虽然都可以对数组进行一维转置,但是ravel和reshape返回的 是视图,而flatten返回的是复制,视图上进行元素修改会改变原数组的值,即会改变原数组,ravel是横向连接,arr1.ravel(order='F')纵向连接
- • vstack和hstack用于合并数组,一个是纵向合并,一个是横向合 np.hstack((arr1,arr2))
- concatenate函数用于合并,np.concatenate((arr1,arr2),axis = 1)# 1代表横向
2)通用函数(基础数学函数)
np.in1d(s,test) #测试s是否在test里面
- intersect1d(x,y) --交集
- union1d(x,y) --并集
- setdiff1d(x,y) --x 减去 x和y的交集后的集合
- setxor1d(x,y) -- x和y的并集减去x和y的交集
(1)重要函数
s = np.array([1,2,3,4,3,1,2,2,4, 6,7,2,4,8,4,5])
np.sort(s)
np.argsort(s)
s.argmax()
s.argmin()
np.where(s>3,1#正确返回,-1#错误返回值)
np.extract(s>3,s)
3)numpy文件读写
(1)文件读取
# 读取文件
data = np.genfromtxt(r'E:\Numpy运用\arr.txt',delimiter=‘,’)
data = np.genfromtxt(r'E:\Numpy运\sales.csv',delimiter=',',skip_header= 1)
# 使用loadtxt读取
data = np.loadtxt(r'E:\Numpy运用\arr.txt',delimiter=',')
(2)文件存储
(3)numpy字符串
![](https://img-blog.csdnimg.cn/20210829155432514.png?x-oss-process=image/watermark,type_ZHJvaWRzYW5zZmFsbGJhY2s,shadow_50,text_Q1NETiBAcXFfMzUxNjg0MjY=,size_18,color_FFFFFF,t_70,g_se,x_16)
[i.title() for i in str_list]
np.char.title(str_arr)
np.char.isalpha(arr)
np.char.count(arr,’a’)
np.char.add(['中国','国庆'],['海军','大阅兵'])
[out] array(['中国海军', '国庆大阅兵'], dtype='<U5')
np.char.multiply(['中国','万岁'],3)
[out] array(['中国中国中国', '万岁万岁万岁'], dtype='<U6')
# 去除字符串指定符号
np.char.strip(['-电动汽车','海洋科技-','-学习python'],'-')
[out] array(['电动汽车', '海洋科技', '学习python'], dtype='<U9')
np.char.replace(['我想学习一下Python','好好学习一下java'],'学习一下','深入学习')
[out] array(['我想深入学习Python', '好好深入学习java'], dtype='<U12')
np.char.islower(arr) #是否包含小写字母
np.char .count(arr,'中') #arr中有几个‘中’
4)numpy运用
(1)随机数生成
![](https://img-blog.csdnimg.cn/20210829160138655.png?x-oss-process=image/watermark,type_ZHJvaWRzYW5zZmFsbGJhY2s,shadow_50,text_Q1NETiBAcXFfMzUxNjg0MjY=,size_18,color_FFFFFF,t_70,g_se,x_16)
np.random.seed(100)
np.random.random(100)
np.random.randint(0,100,size= 100)
np.random.uniform(low=0,high=10,size=100)
np.percentile(da a,[0,25,50,75,100]) #分位数
np.transpose(arr2) #转置矩阵
#逆矩阵
from numpy.linalg import inv
arr2_inv = inv(arr2)
print(arr2_inv)
2. pandas数据库
1)基本操作
(1)常用数据结构
series1 = pd.Series([2.8,3.01,8.99,8.59,5.18])
series2 = pd.Series([2.8,3.01,8.99,8.59,5.18],index = ['a','b','c','d','e'],
name ='这是一 个series’)
series3 = pd.Series(np.array((2.8,3.10,8.99,8.59,5.18)),
index = ['a','b','c','d','e’])
series4 = pd.Series({'北京':2.8,'上海':3.01,'广东':8.99,'江苏':8.59,'浙江':5.18})
list1 = [['张三',23,'男'],['李四',27,'女'],['王二',26,'女']]#使用嵌套列表
df1 = pd.DataFrame(list1,columns=['姓名','年龄','性别'])
df2 = pd.DataFrame({'姓名':['张三','李四','王二'],'年龄':[23,27,26],
'性别':['男','女','女']})
array1 = np.array([['张三',23,'男'],['李四',27,'女'],['王二',26,'女']])# 使用numpy
df3 = pd.DataFrame(array1,columns=['姓名','年龄','性别'],index = ['a','b','c’] )
(2)文件读取与保存
(3)数据筛选
- drop(labels,axis,inplace =True)
- labels表示删除行或者列的标签,axis表示行或列,inplace=True表示是否对原数据生效)
- drop(axis = 0) 指按行操作
- drop(axis = 1) 指按列操作
order.loc[0:2,['order_id','dish es_name’]] #A为行标签,B为列标签
order.loc[3:5,['order_id','dish es_name’]]
order.loc[0:2,['order_id','dishes_name']] #选择对应的行名称和多列
order.loc[order['order_id'] ==458,['order_id','dishes_name']] #按照条件选择
order.iloc[:,[0,2]] #位置索引
order.iloc[2:7,[1,2]]
order.drop(['pay_way','paymen t'],axis=1,inplace=True order.drop(labels = [3,4],inplace = True)
order.rename(columns = {'amounts':'payment'},inplace = True)
#####条件查询
order.loc[order['order_id'] ==458,['order_id','dishes_name']] #按照条件选择
#使用between
order[['dishes_id', 'dishes_name','amounts']][order['amounts'].between(10,30,inclusive=True)]
#使用pd.isin()
order[['dishes_id', 'dishes_name']][order['dishes_name'].isin(['蒙古烤羊腿','大蒜苋菜'])] # dishes_name里面带有['蒙古烤羊腿','大蒜苋菜']
###增删改查
#增
order['payment'] = order['counts']* order['amounts'] #增加一列
#假设我们希望emp_id位于第一列,怎么办,,,df.insert(位置,变量名称,取值)
#删
order.drop('pay_way',axis=1,inplace=True) #删除这一列 ,加inplace代表是否在原数据上操作
order.drop(labels = [3,4],inplace = True) # 删除索引为2对应的行
#改
order.loc[order['order_id']==458,'order_id'] = 45800 #修改数据(按照a条件)
#修改数据
order.rename(columns = {'amounts':'payment'},inplace = True)
order.describe().loc['count'] == 0 #判断计数是否为0
2)pandas高级操作
(1)数据库读取与保存
# 获取MYSQL数据集
import pymysql
import pandas as pd
from sqlalchemy import create_engine
# 按实际情况依次填写MySQL的用户名、密码、IP地址、端口、数据库名
conn=create_engine('mysql+pymysql://用户名:密码@服务器IP:端口/数据库名')
sql1='select * from 库名'
df1=pd.read_sql(sql1,conn)
(2)数据合并
merge1 = pd.concat([df1,df2],axis=1,join='inner’)
merge1 = pd.concat([df1,df2],axis=1,join='outer’)
order_merge = pd.concat([order1,order2,order3],axis=0,ignore_index=False)
order_merge.reset_index(inplace=True)
#•按照主键连接
merge1 = pd.merge(left = df1, right = df2, how = 'right', left_on='id', right_on='Id')#右连接
merge1 = pd.merge(left = df1, right = df2, how = 'outer', left_on='id', right_on='Id') #全连接
#按照索引上的进行合并
merge1 = pd.merge(left = df1, right = df2, how = 'left', left_index=True, right_index=True) #左连接
(3)层次化索引
3)分组聚合和透视图
(1)数据排序
数据.sort_values('Year',ascending = True, na_position='last',inplace = True)
vgsales.sort_values(['NA_Sales','EU_Sales’])
vgsales.sort_values('Year',ascending = True, na_position='last',inplace = True) #升序(缺失值排最后面),inplace =True表示是否作用在原数据上
#重置索引
vgsales.reset_index(inplace = True,drop =True)
#在数据中找到JP_Sales中最小的两个值
vgsales.nsmallest(2,'JP_Sales')
#在数据中找到JP_Sales中最大的两个值
vgsales.nlargest(2,'JP_Sales')
(2)分组聚合
- 使用transform后,表结构与之前保持一样
- transform对整个dataframe的元素进行操作
- 我们可以看到使用transform 和apply 的输出结果形式是不一样的,transform返回与数据同样长度的行,而apply则进行了聚合
数据名.groupby(by = 'Year').mean()
grouped = vgsales[names].groupby(by = 'Year’)
grouped1 = vgsales[names].groupby(by = ['Year','Genre’])
grouped = vgsales[names].groupby(by = 'Year',as_index=True, sort=True) #返回一个分组对象
grouped1 = vgsales[names].groupby(by = ['Year','Genre']) # 返回一个分组对象
#聚合函数 agg是一个作用于series或者DataFrame的函数,主要目的是针对分组后的对象,使用相关函数进行计算
grouped.agg([np.mean,np.sum])
grouped.agg([np.mean,np.sum]).loc[[1980,1981.0],('NA_Sales',['mean','sum'])]
grouped.agg({'NA_Sales':np.sum,'EU_Sales':np.mean}) #对2个变量分别计算不同的统计量
#apply
grouped.apply(np.mean)
vgsales[['NA_Sales','EU_Sales','JP_Sales','Other_Sales']].apply(np.mean,axis=0) #0代表计算列的情况
grouped.mean().transform(lambda x:x*2)
(3)透视图和交叉表
pivot_table( data, index, columns,value, aggfunc, fill_value, margins, margins_name=)
Index : 行分组键
columns: 列分组键
values: 分组的字段,只能为数值型变量
aggfunc: 聚合函数
margins: 是否需要总计
#案例
#margin =True 表示是否需要总计
pd.pivot_table(data= df,index='Year',values='Global_Sales',aggfunc=np.mean,margins=True,margins_name='总计')
# 两个变量列联表汇总
pd.pivot_table(data=df,index='Year',columns='Genre',values='Global_Sales',aggfunc=np.mean,margins=True,margins_name='总计')
#两层索引
pd.pivot_table(data= df,index=['Year','Platform'],values='Global_Sales',aggfunc=np.mean,margins=True, margins_name='总计')
pd.crosstab(index = df['Platform'], columns=df['Genre'],margins=True,normalize='columns') #index表示计算行百分比,columns表示计算列百分比
###交叉表
#是一种计算分组频数的特殊透视表
pd.crosstab(index = df['Platform'], columns=df['Genre'],margins=True)
#按照行进行汇总,计算频数占比
pd.crosstab(index = df['Platform'], columns=df['Genre'],margins=True,normalize='all')#normalize表示的是是否进行频率计算
pd.crosstab(index = df['Platform'], columns=df['Genre'],margins=True,normalize='columns') #index表示计算行百分比,columns表示计算列百分比
4)pandas数据分析预处理
(1)pandas其他函数预算
利用Pandas库中的sample。
DataFrame.sample(n=None, frac=None, replace=False, weights=None, random_state=None, axis=None)
-
n是要抽取的行数。(例如n=20000时,抽取其中的2W行)
-
frac是抽取的比列。(有一些时候,我们并对具体抽取的行数不关系,我们想抽取其中的百分比,这个时候就可以选择使用frac,例如frac=0.8, 就是抽取其中80%)
-
replace:是否为有放回抽样,取replace=True时为有放回抽样。
-
weights这个是每个样本的权重,具体可以看官方文档说明。
-
random_state这个在之前的文章已经介绍过了,可以理解为随机数种子
-
axis是选择抽取数据的行还是列。axis=0的时是抽取行,axis=1时是抽取列(也就是说axis=1时,在列中随机抽取n列,在axis=0时,在行中随机抽取n行)
#上牌时间应该为时间类型,新车价格应该为浮点型类型
sec_cars['Boarding_time'] = pd.to_datetime(sec_cars['Boarding_time'],format ='%Y年%m月',errors = 'coerce')#加上这个以防止数据格式有些数据不匹配
#时间差
sec_cars['diff_day'] = pd.datetime.today() - sec_cars['Boarding_time']
sec_cars['diff_day'] = sec_cars['diff_day']/np.timedelta64(1, 'D')#转化为天数 1代表周期,D代表天数
sec_cars['diff_year'] = pd.datetime.today().year - sec_cars['Boarding_time'].dt.year # 计算年份差
sec_cars['New_price'].str[:-1]
sec_cars['diff_day'] = pd.datetime.today() - sec_cars['Boarding_time']
df = data.sample(n=50000,replace=False)
# 将手机号中间4位隐藏
df.tel = df.tel.apply(lambda x: x.replace(x[3:7],'****'))
grouped_data['SMA_5'] = grouped_data['total_price'].rolling(5).mean()
•pct_change() #计算(后一个 - 前一个)/前一个
•计算变化率
•使用diff函数,效果如下
•diff(1) 代表用下一行减去上一行,例如第三行减去第二行
•dff(2) 代表用下二行减去上一行,例如第三行减去第一行
grouped_data['diff'] = grouped_data['total_price'].diff(1)
(2)数据清洗
1.重复值处理
df[df.duplicated()] #识别重复值
np.sum(df.duplicated())
df.drop_duplicates()
df.drop_duplicates(subset= ['appname','size'],inplace=True) #删除重复值
2.缺失值处理
df.apply(lambda x: sum(x.isnull())/len(x),axis= 0) #缺失比例
###直接删除
df.dropna() 删除有缺失值的行
df.dropna(how='any',axis = 1 ) #只要有缺失,就删除这一列
###填充
df.age.fillna(df.age.mean())
df.age.fillna(df.age.median())
df.fillna(20)
#性别使用众数,年龄使用均值,收入使用中位数
df.fillna(value = {'gender':df.gender.mode()[0],'age':df.age.mean(),'income':df.income.median()})
###插补法
df.age.interpolate(method='polynomial',order=1)
3.异常值处理
(3)数据离散化
-
pandas.cut(x, bins, right=True, labels=None, retbins=False, precision=3, include_lowest=False)
-
参数:
-
x,类array对象,且必须为一维,待切割的原形式
-
bins, 整数、序列尺度、或间隔索引。如果bins是一个整数,它定义了x宽度范围内的等宽面元数量,但是在这种情况下,x的范围在每个边上被延长1%,以保证包括x的最小值或最大值。如果bin是序列,它定义了允许非均匀bin宽度的bin边缘。在这种情况下没有x的范围的扩展。
-
right,布尔值。是否是左开右闭区间
-
labels,用作结果箱的标签。必须与结果箱相同长度。如果FALSE,只返回整数指标面元。
-
retbins,布尔值。是否返回面元
-
precision,整数。返回面元的小数点几位
-
include_lowest,布尔值。第一个区间的左端点是否包含
• 数据离散化就是分箱
• 一般常用分箱方法是等频或者等宽
sunspots.loc[sunspots['counts'] >P99,'counts_new'] = P99
sunspots.loc[sunspots['counts'] <P1,'counts_new'] = P1
sunspots['counts_bin'] = pd.cut(sunspots['counts'],4,labels=range(4))
sunspots['counts_bin'] = pd.qcut(sunspots['counts'],w,labels=range(k))