python科学数据库(一)

目录

1.numpy数据库

1)数组

(1)创建数组

 (2)花式索引

(3) 数组形状改变

2)通用函数

(1)重要函数

3)numpy文件读写

(1)文件读取

(2)文件存储

(3)numpy字符串

         4)numpy运用

(1)随机数生成

2. pandas数据库

1)基本操作

(1)常用数据结构

(2)文件读取与保存

(3)数据筛选

2)pandas高级操作

(1)数据库读取与保存

(2)数据合并

(3)层次化索引

 3)分组聚合和透视图

(1)数据排序

(2)分组聚合

(3)透视图和交叉表

4)pandas数据分析预处理

(1)pandas其他函数预算

(2)数据清洗

(3)数据离散化


1.numpy数据库

1)数组

(1)创建数组

使用array函数创建,语法格式为array(列表或元组)
也可以使用其他函数例如arange、linspace、zeros等创建
# 导入库 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 、resize 、 ravel 、 flatten 、vstack 、 hstack等函数
  1. reshape 是返回视图    arr1.reshape(2,6)resize回直接改变自身;这两个函数主要用于改变数组的形状,请注意区别
  2. ravelflatten对数组直接进行一维转换,展平为一维数组  ravel、flatten和reshape虽然都可以对数组进行一维转置,但是ravel和reshape返回的 是视图,而flatten返回的是复制,视图上进行元素修改会改变原数组的值,即会改变原数组,ravel是横向连接,arr1.ravel(order='F')纵向连接
  3. vstackhstack用于合并数组,一个是纵向合并,一个是横向合    np.hstack((arr1,arr2))
  4. 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)重要函数

排序函数: sort函数和argsort函数,注意argsort返回的是从小到大的索引值
搜索函数: agrmax和argmin函数,分别返回最大值和最小值的索引值
条件赋值: np.where可以自定义返回满足条件的情况,np.extract返回满足条件的 元素值
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)文件读取

可以使用genfromtxt读取txt或者csv文件
可以使用loadtxt读取txt或者csv文件
两个函数功能类似,genfromtxt针对的更多是结构化数据
# 读取文件 
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)文件存储

savetxt(fname, data,delimiter, fmt) #一般常用以上的四个参数,分别为保存的路径,数据,分隔符和格式
np.savetxt(r'E:\云开明培训机构\云开见明培训课件\Numpy运\array.csv',data,delimiter=',',fmt='%.3f' )

(3)numpy字符串

Numpy提供char模块处理字符串,运用向量化运算方式
char模块提供常用的字符串操作函数,如连接、切片、删除、替换等
[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)随机数生成

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)常用数据结构

Series类:
由一组数据以及一组与之对应的数 据标签(即索引)组成;可以通过pandas.Series来创建
Series,每个Series可以看成是 DataFrame的一个列
• 通过pandas.Series来创建Series数据结构。
pandas.Series(data,index,dtype,name)。
上述参数中,data可以为列表,array或者dict。
上述参数中, index表示索引,必须与数据同长度,name代表对象的名称
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})
DataFrame类:
通过pandas.DataFrame来创建Series数据结构。
pandas.Series(data,index,dtype,columns)。
上述参数中,data可以为列表,array或者dict。
上述参数中, index表示行索引, columns代表列名或者列标签
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)文件读取与保存

df = pd.read_csv('meal_order_info.csv',encoding = ‘gbk’)
df = pd.read_csv('meal_order_info.csv',encoding = 'gbk’,nrows=10)

(3)数据筛选

基础索引方式,就是直接引用
order['dishes_name'] = order['dishes_name'].apply(lambda  x: str(x).rstrip())   #消除右边空格
order['dishes_name'] = order['dishes_name'].apply(lambda  x:  sum(isnull()))    #计算空值
ioc[行索引名称或者条件,列索引名称或者标签]
iloc[行索引位置,列索引位置]
增删改查和条件查询
  • drop(labels,axis,inplace =True)
  • labels表示删除行或者列的标签,axis表示行或列,inplace=True表示是否对原数据生效)
  • drop(axis = 0) 指按行操作
  • drop(axis = 1) 指按列操作
熟练掌握drop(labels,axis,inplace=True)的用法
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)数据合并

横向堆叠将两张表或多张表在X轴方向,即横向拼接在一起
纵向堆叠将两张表或多张表在Y轴方向,即纵向拼接在一起
注意使用concat时,axis =1用于横向,0代表纵向
注意join取inner或者outer时,分别代表交集和并集
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)层次化索引

在一个轴上拥有两个或者两个以上 的索引。
使用loc语句进行访问
loc里面接受tuple,如 loc[(a,b),:]。

 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)分组聚合

agg: agg方法灵活,能够对分组对象进行相同的聚合,还可以选择不同的聚合方
法,# agg是一个作用于series或者DataFrame的函数,主要目的是针对分组后的对象,使用相关函数进行计算
apply: apply可以进行聚合计算,还可以按行计算
transform: 返回与数据同样长度的行,无法进行聚合
建议: 建议今后在更多使用apply或者agg
  • 使用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))

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值