一、文件的读写1.csv文件demo.csv文件内容: id,name
1,word
2,word
3,word
4,word
5,null
6,NaN
7,word
8,word
(1).读取.csv文件
1).代码示例import pandas as pd
# 读取指定路径下的文件,并设置以第一行作为列索引
df = pd.read_csv(r'D:\Project\Python\jyputerTest\demo.csv',index_col=0)
print(df)
# 检测数据类型是否是DataFrame
print(type(df))
# 输出:<class 'pandas.core.frame.DataFrame'>
(2).输出.csv文件
1).代码示例# 将df中的指定列的数据写到csv文件中,并设置输出列索引(因为此时的列索引是我们的第一列数据),设置输出头部
df.to_csv('grades.csv',columns=['name'],index=True,header=True)
2.Excel文件
demo.xlsx文件内容
(1).读取Excel文件1).代码示例# 读取指定路径下的Excel文件,并把第一列值作为索引读入
df_xlsx = pd.read_excel(r'D:\Project\Python\jyputerTest\demo.xlsx',index_col=0)
(2).将DataFrame写入Excel1).代码示例
2).此时生成的文件的第二种读取方式# 加载一个Excel文件对象
df_xlsx3 = pd.ExcelFile(r'D:\Project\Python\jyputerTest\demoOut.xlsx')
# 再讲Excel文件对象转成df对象,同时指定索引列为标的第一列数据
newDf = df_xlsx3.parse('sheet1',index_col=0)
# 展示数据
newDf
3.MySQL数据库
(1).读写MySQL1).代码示例# 导入必要模块
import pandas as pd
from sqlalchemy import create_engine
# 初始化数据库连接,使用pymysql模块
# MySQL的用户:root, 密码:111111, 端口:3306,数据库:test,指定编码为utf-8(防止出现乱码)
engine = create_engine('mysql+pymysql://root:111111@localhost:3306/test?charset=utf8')
# 查询语句,选出demo表中的所有数据(主义)
sql = 'select * from demo;'
# read_sql_query的两个参数: sql语句, 数据库连接
df = pd.read_sql_query(sql, engine)
# 输出employee表的查询结果
print(df)
# 新建pandas中的DataFrame, 只有id,num两列
df2 = pd.DataFrame({'id':[1,2,3,4],'num':[12,34,56,89]})
# 将新建的DataFrame储存为MySQL中的数据表,不储存index列
df2.to_sql('mydf', engine, index= False)
# 将从mysql中读取的数据再写到mysql数据库中
df.to_sql('demo2', engine, index=False)
# 打印执行成功
print('Read from and write to Mysql table successfully!')
# 在msyql的客户端可以查询相应的表以及表中的内容
二、DataFrame对象基本操作1.数据提取与其他操作(0).DataFrame的添加删除操作
(1).根据索引或者列名取值# 1.整数作为索引:df.iloc[n],默认查找第n行
df.iloc[0]
# 2.按索引提取区域行数值(区间的值是左闭右开的)
df.iloc[0:5]
# 3.列表作为索引:查找列表中数字对应行号的数据,如,当输入[0,2]时,对应查找行号为0和2的数据,而不是0-2行
df.iloc[[0,2]]
# 4.按索引提取单行的数值
df.loc[3]
# 5.提取4日之前的所有数据
df[:'2013-01-04']
# 6.设置日期为索引(date这一列的数据都是日期格式的)
df=df.set_index('date')
# 7.重设索引
'''
将排序后的索引重新排序
df.reset_index(drop)
其中drop为布尔型值:
True表示修改原始数据的索引。
False保留原始数据索引序列。
'''
df.reset_index()
# 8.如取Name列数据的前5行
df['Name'][:5]
print(df['Name'][:5])
# 9.获取多列数据时需要传入一个列表对象
cols = ['name', 'province_name', 'city_name', 'city_code', 'area', 'addr']
# 10.获取多列数据的前2行数据
df[cols][:2]
print(df[cols])
# 11.判断city列中的所有值是否有值为'beijing'
df['city'].isin(['beijing'])
# 12.判断city列里是否包含beijing和shanghai,然后将符合条件的数据提取出来
df.loc[df['city'].isin(['beijing','shanghai'])]
(2).查看DataFrame的前后几行
(3).展示DataFrame列名# 1.展示列名
col_names = df.columns
print(col_names)
# 2查看下col_names格式
type(col_names)
# 3.将col_names转化为list
col_list = col_names.tolist()
print(col_list)
(4).矢量化操作(批量操作)
2.常见操作示例小结(0).字符串(str)的处理print(df['股票代码']) # 取当前列的所有值
print('sz000002'[:2]) # 根据索引取当前指定列的值
# 加上str之后可以使用常见的字符串函数对整列进行操作;
print(df['股票代码'].str[:2]) # 通过索引获取字符串中字符(不写默认是从0开始)
print(df['股票代码'].str.upper()) # 将字符串中的小写字母转为大写字母。
print(df['股票代码'].str.lower()) # 转换字符串中所有大写字符为小写。
print(df['股票代码'].str.len()) # 计算字符串的长度,length
df['股票代码'].str.strip() # strip操作,把字符串两边的空格去掉
print(df['股票代码'].str.contains('sh')) # 判断字符串中是否包含某些特定字符
print(df['股票代码'].str.replace('szzzz', 'sz')) # 进行替换,将szzzz替换成sz;格式:str.replace(old, new[, max]),其中max是指定替换不超过max次
print(df['新浪概念'].str.split(';')) # 对字符串进行分割
print(df['新浪概念'].str.split(';').str[:2]) # 分割后取第一个位置
print(df['新浪概念'].str.split(';', expand=True)) # 分割后并且将数据分列
# 8.字符串.str的常见操作
# 定义变量: name = 'abcdaaaefg'
(1). strip() 去除前后端的空格
(2).判断变量name是否以al开头,并输出 开头查找 startswith()
print(name.startswith('ab'))
(3).判断变量name是否以Nb结尾,并输出 结尾查找 endswith()
print(name.endswith('Nb'))
(4).将name变量中所有的a替换为 p 替换方法 replace(old,new)
print(name.replace('a','p'))
(5).判断name变量中对应的值'a'出现几次 查找元素出现的次数方法 count()
print(name.count('a'))
(6).判断name变量中前四位中'a'出现几次. 解释:先把name的前四位找出来,然后用count计算l的出现次数
a = name[0:5]
print(a.count('a'))
(7).找到name变量中'f'的索引; index方法:找不到会报错;find方法:找不到返回-1
print(name.index('f'))
print(name.find('f'))
(8).for循环遍历集合
s='fsfaf'
for i in s:
print(i)
# str()函数: 返回一个对象的string格式(也就是将对象转成字符串)
str(object='', encoding='utf-8') # 可以通过object参数指定传入的对象
str() # 也可以直接将对象传入
(1).数据清洗1).去重清洗
2).空值清洗①.删除空值并重新设置索引# (1),删除空值(NaN):调用函数先删除空值,然后重新设置索引! ★★
df = df.dropna().reset_index(drop=True)
# 2.从mysql数据库中取值
from sqlalchemy import create_engine
import pymysql
db = create_engine('mysql+pymysql://root:111111@localhost:3306/migrate')
import pandas as pd
df = pd.read_sql('testavg',db)
# 直接调用df对象的dropna方法来对缺失值进行删除
# dropna( axis = 0 /1 )参数axis表示轴选择,axis=0 代表行,axis=1 代表列。
df.dropna()
②.使用默认值填充空值
③.使用平均值填充空值# 3.用平均值进行填充
from sqlalchemy import create_engine
import pymysql
db = create_engine('mysql+pymysql://root:111111@localhost:3306/migrate')
import pandas as pd
import numpy as np
df = pd.read_sql('testavg',db)
# df.isna() 判断出df对象中的空值(如果为空,则为true)
# np.where(df.isna()) 返回空值对应的行索引和列索引以series的方式封装在了元组中
# np.where(df.isna())[0] 从元组中取出行索引(0代表行);
# 只写一个数字的时候是取一行,然后放在列表中就可以取多行,并且可以加逗号之后就取某一列。
# df.iloc[np.where(df.isna())[0]] 根据索引将值取出来,返回的是一个新的df对象
# for a in df.iloc[np.where(df.isna())[0]].itertuples(): 遍历df对象,返回的是元组,可以通过下标取出对应的值;并对其进行遍历(在遍历df对象的时候就可以采用这种方法)
#
# row[0] 得到每一个行索引(这是df对象的)
# 下一行的3是指的第3列
# df.iloc[row[0],3] 通过行索引和指定的列取的每个对应的df对象的值(也就是对应的每一个空值所在的位置)
# df['jobname'] 根据标签取值,取到当前标签下的所有值
# df['jobname'].str.contains(row[3]) 比较两个字符串是否向相等用contains方法,而且contains方法是在str下的;返回值是布尔类型的
# df[df['jobname'].str.contains(row[3])] 取出当前比较的结果,得到的是布尔类型的值(此时就已经将row[3]中对应的每个属性的所有值进行分组了)
# df[df['jobname'].str.contains(row[3])] 根据不同的布尔值,从而取出每组中的值
# df[df['jobname'].str.contains(row[3])].mean() 对所有的数值型数据进行求平均值,
# df[df['jobname'].str.contains(row[3])].mean()['salary'] 只取出salary标签的平均值
# int(df[df['jobname'].str.contains(row[3])].mean()['salary']) 强制转换成int类型的
# df.iloc[row[0],3] = int(df[df['jobname'].str.contains(row[3])].mean()['salary']) 最后对空值赋值从而实现替换空值
for row in df.iloc[np.where(df.isna())[0]].itertuples():
df.iloc[row[0],3] = int(df[df['jobname'].str.contains(row[3])].mean()['salary'])
print(df)
④.使用众数填充空值
⑤.使用中位数填充空值# 5.用中位数进行填充
from sqlalchemy import create_engine
import pymysql
db = create_engine('mysql+pymysql://root:111111@localhost:3306/migrate')
import pandas as pd
import numpy as np
df = pd.read_sql('testavg',db)
# df.isna() 判断出df对象中的空值(如果为空,则为true)
# np.where(df.isna()) 返回空值对应的行索引和列索引以series的方式封装在了元组中
# np.where(df.isna())[0] 从元组中取出行索引(0代表行);
# 只写一个数字的时候是取一行,然后放在列表中就可以取多行,并且可以加逗号之后就取某一列。
# df.iloc[np.where(df.isna())[0]] 根据索引将值取出来,这里是传入的列表,然后就可以取出多行来。
# for a in df.iloc[np.where(df.isna())[0]].itertuples(): 将DataFrame迭代为元祖;并对其进行遍历。
#
# row[0] 得到每一个行索引(这是df对象的)
# df.iloc[row[0],3] 通过行索引和指定的列取的每个对应的df对象的值(也就是对应的每一个空值)
# df['jobname'] 根据标签取值,取到当前标签下的所有值
# df['jobname'].str.contains(row[3]) 比较两个字符串是否向相等用contains方法,而且contains方法是在str下的;返回值是布尔类型的
# df[df['jobname'].str.contains(row[3])] 取出当前比较的结果,得到的是布尔类型的值(此时就已经将row[3]中对应的每个属性的所有值进行分组了)
# df[df['jobname'].str.contains(row[3])] 根据不同的布尔值,从而取出每组中的值
# df[df['jobname'].str.contains(row[3])]['salary'] 取出salary标签的值
# df[df['jobname'].str.contains(row[3])]['salary'].median() salary标签下的中位数
# int(df[df['jobname'].str.contains(row[3])]['salary'].median()) 强制转换成int类型的
# df.iloc[row[0],3] = int(df[df['jobname'].str.contains(row[3])]['salary'].median()) 最后对空值赋值从而实现替换空值
# row 是代表每一行的数据
for row in df.iloc[np.where(df.isna())[0]].itertuples():
df.iloc[row[0],3] = int(df[df['jobname'].str.contains(row[3])]['salary'].median())
⑥.使用插值法填充空值
⑦.将空值作为一个新的label处理from sqlalchemy import create_engine
import pymysql
db = create_engine('mysql+pymysql://root:111111@localhost:3306/migrate')
import pandas as pd
# 数据来源是MySQL
df = pd.read_sql('testavg',db)
# 设置一个新的lable存下空值
df['空值'] = df.iloc[np.where(df.isna())[0]].salary
⑧.使用KNN填补缺失值
3).异常值处理①判断是否有异常值import numpy as np
# ser1表示传入DataFrame的某一列
def three_sigma(ser):
# 求的是某一列的平均值啊(也就u)
mean_value = ser.mean()
# 求标准差(也就是σ)
std_value = ser1.std()
# 位于(u-3σ,u+3σ)区间的数据是正常的,不在这个值的数据便是异常值,其中s值的是方差
# 一旦发现异常值就标注为true,否则标注为false,所以这里的返回值是布尔值
rule = (ser < mean_value-3*std_value)|(ser > ser.mean()+3*ser1.std())
# 获取异常数据,因为当前列就是一个Series,可以直接用布尔值取数据
outrange = ser[rule]
# 将判断出来的异常值返回
return outrange
②处理异常值(替换)
4).数据标准化
# 实现函数:
def programmer_2():
# 定义文件的路径
datafile = path + '/data/normalization_data.xls'
# 将利用Pandas将数据读取进来
data = pd.read_excel(datafile, header=None)
# 最小-最大规范化
print((data - data.min()) / (data.max() - data.min()))
# 零-均值规范会(也就是标准差标准化)
print((data - data.mean()) / data.std())
# 小数定标规范化
print(data / 10**np.ceil(np.log10(data.abs().max())))
5).连续属性的离散化
6).对小数位数的精度处理(1)对于要求较小的精度
将精度高的浮点数转换成精度低的浮点数。
1.round()内置方法
round()不是简单的四舍五入的处理方式。
>>> round(2.5)
2
>>> round(1.5)
2
>>> round(2.675)
3
>>> round(2.675, 2)
2.67
round()如果只有一个数作为参数,不指定位数的时候,返回的是一个整数,而且是最靠近的整数(这点上类似四舍五入)。
但是当出现.5的时候,两边的距离都一样,round()取靠近的偶数
(2)如果需要精确小数位数到17位之后,参考以下博客:
https://www.cnblogs.com/yfz1552800131/p/5363297.html
7).删除满足指定条件的元素
(2).筛选操作# 0.根据指定的条件,筛选出相关拿数据
print(df['股票代码'] == 'sh000002') # 判断股票代码是否等于sz000002
print(df[df['股票代码'] == 'sz000002']) # 将判断为True的输出:选取股票代码等于sz000002的行
print(df[df['股票代码'].isin(['sz000002', 'sz000003 ', 'sz000004'])]) # 选取股票代码等于sz000002,sz000003,sz000004的行
print(df[df['收盘价'] >= 24.0]) # 选取收盘价大于24的行
print(df[(df.index >= '03/12/2016') & (df.index <= '06/12/2016')]) # &:与操作(并且)
print(df[(df.index >= '03/12/2016') | (df.index <= '06/12/2016')]) # |:或操作(或者)
# 使用与,或,非三个条件配合大于,小于,等于对数据进行筛选,并进行计数和求和。
# 1,使用'与'进行筛选
df.loc[(df['age'] > 25) & (df['city'] == 'beijing'), ['id','city','age','category','gender']]
# 2,使用'或'进行筛选
df.loc[(df['age'] > 25) | (df['city'] == 'beijing'), ['id','city','age','category','gender']].sort(['age'])
# 3,使用'非'条件进行筛选
df.loc[(df['city'] != 'beijing'), ['id','city','age','category','gender']].sort(['id'])
# 4,对筛选后的数据按city列进行计数
df.loc[(df['city'] != 'beijing'), ['id','city','age','category','gender']].sort(['id']).city.count()
# 5,使用query函数进行筛选
df.query('city == ['beijing', 'shanghai']')
# 6,对筛选后的结果按prince进行求和
df.query('city == ['beijing', 'shanghai']').price.sum()
(3).常见的数据统计与计算函数
# 数据采样,计算标准差,协方差和相关系数
# 简单的数据随机采样(也就是说从df中随机取出三组数)
df.sample(n=3)
# 手动设置采样权重
weights = [0, 0, 0, 0, 0.5, 0.5]
df.sample(n=2, weights=weights)
# 采样后不放回
df.sample(n=6, replace=False)
# 采样后放回
df.sample(n=6, replace=True)
# 数据表描述性统计
df.describe().round(2).T # round函数设置显示小数位,T表示转置
# 计算列的标准差
df['price'].std()
# 计算两个字段间的协方差
df['price'].cov(df['m-point'])
# 数据表中所有字段间的协方差
df.cov()
# 两个字段的相关性分析 ★★
df['price'].corr(df['m-point']) #相关系数在-1到1之间,接近1为正相关,接近-1为负相关,0为不相关
# 数据表的相关性分析
df.corr()
(4).排序操作
# coding=utf-8
import pandas as pd
import numpy as np
# 以下实现排序功能。
# 先创建一个Series对象和DataFrame对象
s=pd.Series([3,4,1,6],index=['b','a','d','c'])
df = pd.DataFrame([[2,4,1,5],[3,1,4,5],[5,1,4,2]],columns=['b','a','d','c'],index=['one','two','three'])
df = pd.DataFrame([['2012-3-4','2013-2-4','2014-11-4','2016-2-24'],
['2019-1-24','2018-12-4','2017-11-14','2017-2-24'],
['2012-3-4','2013-2-4','2014-11-4','2016-2-24']],columns=['a','b','c','d'])
print(df)
print(s)
# 降序排序,默认是升序排序★★
list.sort(reverse=True)
# 'series通过索引进行排序:'
print(s.sort_index())
# 'series通过值进行排序:'
print(s.sort_values())
# 'dataframe根据行索引进行降序排序(排序时默认升序,调节ascending参数):'
print(df.sort_index(ascending=False))
# 'dataframe根据列索引进行排序:'
print(df.sort_index(axis=1))
# 'dataframe根据指定的列的值进行排序:'
print(df.sort_values(by='a'))
# '通过多个列索引进行排序:'
print(df.sort_values(by=['a','c']))
# by参数指定按照那一列进行排序,acsending参数指定是升序还是降序,默认是升序即acsending=1,当acsending=0时降序
print(df.sort_values(by=['交易日期'], ascending=1))
# 按照多列进行排序
print(df.sort_values(by=['股票名称', '交易日期'], ascending=[1, 1]))
# 在指定排序字段的时候可以直接使用字段名进行排序,inplace参数表示在排序的之后修改原来df中的值,False则是只返回排序的结果
df.sort_values('xxx',inplace=True)
(5).数据汇总
# 测试2:
# 创建一个测试对象
df = pd.DataFrame({ 'A': ['a', 'b', 'a', 'c', 'a', 'c', 'b', 'c'],
'B': [2, 8, 1, 4, 3, 2, 5, 9],
'C': [102, 98, 107, 104, 115, 87, 92, 123]})
Out[1]:
A B C
0 a 2 102
1 b 8 98
2 a 1 107
3 c 4 104
4 a 3 115
5 c 2 87
6 b 5 92
7 c 9 123
'''
# 按A列分组(groupby),获取其他列的均值(mean)
df.groupby('A').mean()
'''
Out[2]:
B C
A
a 2.0 108.000000
b 6.5 95.000000
c 5.0 104.666667
'''
# 按先按A列再按B列进行分组,
df.groupby(['A','B']).mean()
'''
Out[3]:
C
A B
a 1 107
2 102
3 115
b 5 92
8 98
c 2 87
4 104
9 123
'''
# 分组后,可以选取单列数据,或者多个列组成的列表(list)进行运算
s = df.groupby('A')
s['B'].mean() # 只选择B列
s[['B','C']].mean() # 选择B列和C列,用一个列表封装起来
'''
Out[4]:
A
a 2.0
b 6.5
c 5.0
Out[5]:
B C
A
a 2.0 108.000000
b 6.5 95.000000
c 5.0 104.666667
'''
# 可以针对不同的列选用不同的聚合方法
s.agg({'B':'mean', 'C':'sum'})
'''
Out[6]:
B C
A
a 2.0 324
b 6.5 190
c 5.0 314
'''
(6).pandas中的'size,shape,len,count,value_counts'之间的不同使用
(7).pandas对日期的处理小结
1).设置当前列为索引列# 当前df对象中含有一个date列,其中都是时间格式的数据
# (1).先对数据进行类型转换,方便接下来的筛选数据和统计数据
df['date'] = pd.to_datetime(df['date']) #将数据类型转换为日期类型
df = df.set_index('date') # 将date设置为index
2).按日期筛选数据①.按年度获取数据
②.获取某月的数据print(df['2013-11'])
③.获取具体某天的数据
3).按日期统计数据①.按年统计数据# 1.按年统计,但仍以完整的日期显示
print(df.resample('AS').sum())
# 'AS'是每年第一天为开始日期, 'A是每年最后一天
'''
number
date
2013-01-01 51
2014-01-01 453
2015-01-01 743
2016-01-01 1552
2017-01-01 92
'''
# 2.按年统计数据并按年显示
print(df.resample('AS').sum().to_period('A'))
'''
number
date
2013 51
2014 453
2015 743
2016 1552
2017 92
'''
②.按季度统计数据
③.按月统计数据# 1.按月统计数据,但仍以完整的日期显示
print(df.resample('M').sum().head())
'''
number
date
2013-10-31 10
2013-11-30 14
2013-12-31 27
2014-01-31 16
2014-02-28 4
'''
# 'MS'是每个月第一天为开始日期, 'M'是每个月最后一天
'''
number
date
2013-10-31 10
2013-11-30 14
2013-12-31 27
2014-01-31 16
2014-02-28 4
'''
# 2.按月统计并按月显示
print(df.resample('M').sum().to_period('M').head())
'''
number
date
2013-10 10
2013-11 14
2013-12 27
2014-01 16
2014-02 4
'''
④.按周统计数据
4).时间差的数据转换# 这样计算时间差会出现单位:days
res = pd.DataFrame(pd.to_datetime(data['LOAD_TIME']) - pd.to_datetime(data['FFP_DATE'])) # 234days
# 只取时间,而不带days
res_new = res.dt.days # 234
# 这样可以将日期的数据转换成月份格式的数据()
res.map(lambda x: x / np.timedelta64(30 * 24 * 60, 'm'))
(8).Numpy的where的用法
(9).数据表的合并操作# (1).merge
'''
多表之间的连接也是非常常见的数据库操作,连接分内连接和外连接,在数据库语言中通过join关键字实现.
注意:默认情况下,merge函数实现的是两个表之间的内连接,即返回两张表中共同部分的数据。
可以通过how参数设置连接的方式,left为左连接;right为右连接;outer为外连接。
可以使用on关键字实现指定按某个列去合并!
'''
# 这里的df和df1是两个Dataframe对象
df=pd.merge(df,df1,how='inner',on='name') # 匹配合并:交集(这里两个df中都有name列)
df_left=pd.merge(df,df1,how='left') # 左连接(此时会保留左表(df)的数据)
df_right=pd.merge(df,df1,how='right') # 右连接(此时会保留右表(df1)的数据)
df_outer=pd.merge(df,df1,how='outer') # 并集(两张表取并集)
# (2).append
result = df1.append(df2)
'''
df1:
A B
0 A0 B0
1 A1 B1
df2:
A B
3 A3 B3
4 A4 B4
result:
A B
0 A0 B0
1 A1 B1
3 A3 B3
4 A4 B4
'''
# (3).join
result = left.join(right, on='key') # 根据key列,将左表和右表联系在一起
'''
left:
A B
0 A0 B0
1 A1 B1
right:
C D
0 C3 D3
1 C4 D4
result:
A B C D
0 A0 B0 C0 D0
1 A1 B1 C1 D1
'''
# (4).concat
frames = [df1, df2, df3] # 指定三个df对象
result = pd.concat(frames) # 将三个df对象的值合并到一个df对象中
'''
df1:
A B
0 A0 B0
1 A1 B1
df2:
A B
3 A3 B3
4 A4 B4
df3:
A B
5 A5 B5
6 A6 B6
result:
A B
0 A0 B0
1 A1 B1
3 A3 B3
4 A4 B4
5 A5 B5
6 A6 B6
'''
|
|
来自: NeighborMrSun > 《语法技巧》