Pandas 详细教程:
1.Pandas Series 简介
Pandas 是 Python 中一个强大的数据处理库,广泛应用于数据分析、数据清洗、数据探索等领域。Pandas 提供了两种主要的数据结构:Series
和 DataFrame
。Series
是一种一维标签化数组,可以包含任何数据类型(整数、字符串、浮点数、Python 对象等)。在 Pandas 中,Series
可以看作是带有标签的一维数组,这些标签被称为索引。
1.1创建 Series
创建 Series
对象是 Pandas 数据处理的第一步。我们可以通过以下方式创建一个 Series
对象:
import pandas as pd
# 创建一个包含字符串的 Series
data = ['cici', 'jiki', 'ji', 'jpo']
s = pd.Series(data=data, index=[1, 2, 3, 4])
print(s)
输出结果:
1 cici
2 jiki
3 ji
4 jpo
dtype: object
在这个例子中,我们创建了一个包含四个字符串的 Series
对象,并且为每个元素指定了一个索引。索引是可选的,如果不指定索引,Pandas 会自动为每个元素分配一个从 0 开始的整数索引。
1.2索引和切片
索引是 Pandas Series
的一个核心特性,它允许我们快速访问和操作数据。
1.2.1位置索引切片
我们可以使用位置索引来进行切片,这种方式是基于整数位置的,包含切片的开始索引,但不包含结束索引:
print(s[0:3:1]) # 位置索引切片,含头不含尾
输出结果:
1 cici
2 jiki
dtype: object
在这个例子中,我们选择了索引从 0 到 2 的元素(即索引 1 和 2 的元素),步长为 1。
###1.2.2 标签索引切片
我们也可以使用标签来进行切片,这种切片是基于标签的,是包含头尾的:
index = ['张三', '李四', '糊糊']
data = [89, 98, 96]
s = pd.Series(data=data, index=index)
print(s)
print(s['张三':'糊糊']) # 标签索引切片,含头含尾
输出结果:
张三 89
李四 98
糊糊 96
dtype: int64
张三 89
李四 98
糊糊 96
dtype: int64
在这个例子中,我们选择了从 ‘张三’ 到 ‘糊糊’ 的所有元素。
1.2.3根据标签选择
我们还可以根据特定的标签来选择数据,这种方式非常灵活,可以直接通过标签名来访问数据:
print(s[['张三', '糊糊']])
输出结果:
张三 89
糊糊 96
dtype: int64
这种方式允许我们快速访问特定的数据,而不需要关心它们在 Series
中的位置。
1.3统计操作
Pandas Series
支持多种统计操作,如求和、平均值、最大值、最小值等:
print(s.sum()) # 求和
print(s.mean()) # 平均值
print(s.max()) # 最大值
print(s.min()) # 最小值
1.3.1布尔索引
布尔索引允许我们基于条件选择数据:
print(s[s > 90]) # 选择所有大于 90 的元素
1.3.2字符串操作
对于字符串数据,Pandas Series
提供了丰富的字符串处理功能:
s_str = pd.Series(['hello', 'world', 'pandas', 'python'])
print(s_str.str.upper()) # 将所有字符串转换为大写
###2. Pandas DataFrame 详解:创建、转换与数据查看
2.1创建 DataFrame
DataFrame
可以通过多种方式创建,其中一种常见的方法是使用字典来创建:
import pandas as pd
data = {
'名称': ['风扇', '笔记本'],
'单价': [320, 8000],
'数量': [100, 120]
}
df = pd.DataFrame(data=data)
print(df)
输出结果:
名称 单价 数量
0 风扇 320 100
1 笔记本 8000 120
在这个例子中,我们创建了一个包含产品名称、单价和数量的 DataFrame
。字典的键成为了 DataFrame
的列名,而键对应的值则成为了列的数据。
###2.2行列转换
行列转换是数据分析中常见的操作,Pandas 提供了非常简洁的方法来实现这一点:
pd.set_option('display.unicode.east_asian_width', True) # 规整格式
new_df = df.T
print(new_df)
输出结果:
0 1
名称 风扇 笔记本
单价 320 8000
数量 100 120
使用 .T
属性,我们可以轻松地将 DataFrame
的行列进行转换。
###2.3 查看数据
在处理数据时,经常需要查看数据的前几行或后几行,Pandas 提供了 head
和 tail
方法来实现这一功能:
print('查看前N条数据\n', df.head(1))
print('查看后N条数据\n', df.tail(1))
输出结果:
查看前N条数据
名称 单价 数量
0 风扇 320 100
查看后N条数据
名称 单价 数量
1 笔记本 8000 120
head
方法默认显示前 5 行数据,而 tail
方法默认显示后 5 行数据。通过传递参数,我们可以指定显示的行数。
###2.4查看行和列
了解 DataFrame
的行数和列数是数据探索的一部分,可以通过 shape
属性来获取:
print('行', df.shape[0], '列', df.shape[1])
输出结果:
行 2 列 3
##3.导入数据
**3.1导入外部数据,导入Excel文件
格式:
pd.read_excel(io,sheet_name,header)
io:文件名
sheet_name:表示工作表
header:默认为0,取第一行的值为列名,数据为除列名以外的数据,如果数据不包含列名,则设置header=None
import pandas as pd
df=pd.read_excel('鞋子评论信息.xlsx',sheet_name='码数分析',header=None)
print(df)
3.1.2导入一列数据
import pandas as pd
df=pd.read_excel('学生信息管理.xlsx',sheet_name='课程及格学生名单',usecols=[1])
print(df)
3.1.3导入多列数据(导入学生的姓名和成绩两列)
import pandas as pd
df=pd.read_excel('学生信息管理.xlsx',sheet_name='课程及格学生名单',usecols=['姓名','总成绩'])
print(df)
3.2导入csv文件
pd.read_csv(filepath_or_buffer,sep=‘,’,header,encoding=None)
参数说明:
**.**filepath_or_buffer:字符串、文件路径、也可以是URL链接
**.**sep:字符串、分隔符
**.**header:指定作为列名的行,默认值为0,即取第一行的值为列名。数据为除列名以外的数据,若数据不包括列表,则设置header=None
**.**encoding:字符串,默认值None,文件编码格式
import pandas as pd
pd.set_option('display.unicode.east_asian_width',True)
df=pd.read_csv('鞋子评论信息.csv',sep=',',encoding='gbk')
print(df.head())
3.3导入文本文件
import pandas as pd
pd.set_option('display.unicode.east_asian_width',True)
df=pd.read_csv('wb.txt',sep='\t',encoding='gbk',header=None)
print(df.head())
3.3导入网页文件
pd.read_html(io,match=‘.+’,flavor,header,encoding)
**.**io:字符串,文件路径,也可以是URL链接,网址不接受https
**.**match:正则表达式
**.**flavor:解释器默认为’lxml’
**.**header:指定列标题所在行
**.**encoding:文件的编码格式
import pandas as pd
url='http://www.espn.com/nba/salaries'
df=pd.DataFrame()#创建一个空的DataFrame对象
df.append(pd.read_html(url,header=0)) # DataFrame添加数据
print(df)
#保存为csv文件
df.to_csv('nbasalary.csv',index=False)
##4.数据抽取 ##
4.1代码示例:
import pandas as pd
pd.set_option('display.unicode.east_asian_width', True)
data = [[45, 65, 100], [56, 45, 50], [67, 67, 67]]
index = ['张三', '李四', '王五']
columns = ['数学', '语文', '英语']
df = pd.DataFrame(data=data, index=index, columns=columns)
print(df)
print('---------------------------')
# 提取行数据
print(df.loc['张三']) # 行索引
print('-------提取多行数据(张三和王五)--------------------')
print(df.loc[['张三', '王五']])
print(df.iloc[[0, 2]])
print('-----提取连续的多行数据(从张三到王五)--------------')
print(df.loc['张三':'王五'])
print('----------------')
print(df.iloc[1::]#iloc[start:stop:step]
打印结果:
数学 语文 英语
张三 45 65 100
李四 56 45 50
王五 67 67 67
---------------------------
数学 45
语文 65
英语 100
Name: 张三, dtype: int64
-------提取多行数据(张三和王五)--------------------
数学 语文 英语
张三 45 65 100
王五 67 67 67
数学 语文 英语
张三 45 65 100
王五 67 67 67
-----提取连续的多行数据(从张三到王五)--------------
数学 语文 英语
张三 45 65 100
李四 56 45 50
王五 67 67 67
---------------------------
数学 语文 英语
李四 56 45 50
王五 67 67 67
##5.数据清洗 ##
5.1查看缺失值
import pandas as pd
pd.set_option('display.unicode.east_asian_width', True)
df=pd.read_excel('课程记录.xls')
print(df)
print('-----------------')
print(df.info())#查看是否有缺失值
print('-----------------')
print(df.isnull())#判断缺失值,不为NaN为False
print(df.notnull())#判断缺失值,不为NaN为False
5.2缺失值的删除
#删除的是所有含NAN的空缺值
import pandas as pd
pd.set_option('display.unicode.east_asian_width', True)
df=pd.read_excel('课程记录.xls')
df=df.dropna()
print(df)
5.2.3删除指定的空缺值
import pandas as pd
pd.set_option('display.unicode.east_asian_width', True)
df=pd.read_excel('课程记录.xls')
df=df[df['课程总数量'].notnull()]
print(df)
5.3填充数据
import pandas as pd
pd.set_option('display.unicode.east_asian_width', True)
df=pd.read_excel('课程记录.xls')
df['课程总数量']=df['课程总数量'].fillna(0)#将数值填充为0
print(df)
5.4 重复值的处理
import pandas as pd
pd.set_option('display.unicode.east_asian_width', True)
df=pd.read_excel('课程记录.xls')
#判断是否具有重复值
print(df.duplicated())
#去除全部的重复数据
df=df.drop_duplicates()
print(df)
print('-------------------------')
#去除指定列的重复数据,保留重复行的最后一行
df=df.drop_duplicates(['实际支付金额'],keep='last')
print(df)
print('-------------------------')
#直接删除,保留一个副本
df1=df.drop_duplicates(['买家实际支付金额'],inplace=False)
print(df1)
6.数据提取之提取区域数据
import pandas as pd
pd.set_option('display.unicode.east_asian_width', True)
data = [[45, 65, 100], [56, 45, 50], [67, 67, 67]]
index = ['张三', '李四', '王五']
columns = ['数学', '语文', '英语']
df = pd.DataFrame(data=data, index=index, columns=columns)
print(df)
print(df.loc[['张三','王五'],['数学','语文']])
print('-------------------------')
print(df.iloc[0,0])#第0行,第0列
print(df.iloc[0:2,0:2])#,前是行切片
打印结果:
数学 语文 英语
张三 45 65 100
李四 56 45 50
王五 67 67 67
数学 语文
张三 45 65
王五 67 67
-------------------------
45
数学 语文
张三 45 65
李四 56 45
提取语文成绩大于60学生信息
print(df.loc[df['语文']>=60])
提取语文和数学均大于60的学生信息
print(df.loc[(df['语文']>=60)&(df['数学']>=60)])
提取列名进行提取
print(df[['数学'],['英语']])
提取所有行的数学和英语
print(df.loc[:,['数学'],['英语']])
利用索引提取指定列
print(df.iloc[:,[0,2]])
7.按照列增加数据
#采用直接赋值的方式
df['政治']=[90,89,100]
print(df)
#使用loc属性在dataframe的最后一列增加
df.loc[:,'化学']=[100,56,98]
print(df)
#在指定索引位置插入一列
lst=[100,39,89]
df.insert(1,'历史',lst)
print(df)
8.按行增加数据
直接赋值
df.loc['陈六']=[96,89,58]
print(df)
#新建一个dataframe
new_df=pd.DataFrame(
data={'数学':[96,59],'语文':[78,86],'英语':[85,78]},
index=['章子义','里小']
)
print(new_df)
df=df.append(new_df)
print(df)
9.修改数据
#直接使用columns属性
df.cloumns=['数学上','语文上','英语上']
print(df)
#rename,inplace是否直接修改dataframe
df.rename(columns={'数学上':'数学下',~},inplace=True)
print(df)
9.1修改行标题
#直接赋值
df.index=list('123')
print(df)
#rename()
df.rename({'1 :'sd',~}, inplace=True,axis=0)#修改行
print(df)
9.2修改一整行
df.loc['张三']=[100,36,69]
print(df)
df.iloc[0,:]=[90,90,90]#修改0行所有列
print(df)
9.3修改整列数据
df.loc[:,'数学']=[100,100,036]
df.iloc[:,0]=90
10.删除数据
删除数学列
df.drop(['数学'],axis=,inplace=True)
带条件的删除
df.drop(df[df['数学']<60.index[1],inplace=True)#删除行索引为李四的成绩
11.设置索引
import pandas as pd
s=pd.Series([11,22,33],index=[1,2,3])
print(s)
#重设置索引
print(s.reindex(range(1,6)))
#使用0进行填充
print(s.reindex(range(1,6),fill_value=0))
#向前后进行填充
print(s.reindex(range(1,6),method='ffill'))
print(s.reindex(range(1,6),method='bfill'))
使用dataframe进行设置索引
print(df.reindex([~])) #重新设置行索引
print(df.reindex(columns=[]))#列索引
print(df.reindex(index=[],columns=[]))
设置某列为行索引
import pandas as pd
df=pd.read_excel('~.xls')
df=df.set_index(['~'])
print(df)
数据清洗后重新设置连续索引
import pandas as pd
df=pd.read_excel('~.xls')
df=df.dropna().reset_index(drop=True)
print(df)
数据的排序
#指定列排序
import pandas as pd
df=pd.read_excel('~.xls')
df=df.sort_value(by='成交金额',ascending=False)
print(df.head())
#根据多列进行排序
df=df.sort_value(by=['数量','成交金额'],ascending=False)#数量相同的话,成交金额降序
数据的排名
df['顺序排名']=df['数量'].rank(ascending=False)
print(df)
数据计算
df['总成绩']=df.sum(axis=1)#按照行相加
计算平均值
df=df.append(df.mean(),ignore_index=True)#按照列计算平均值
计算最大值
df=df.append(df.max(),ignore_index=True)
计算中位数
df=df.append(df.median(),ignore_index=True)
计算众数
print(df.mode())#三科成绩众数
print(df.mode(axis=1))#行中众数
print(df['数学'].mode())#数学的众数
计算方差
print(df.var(axis=1))#pandas采用方差和除以样本减一
计算标准差
print(df.std())
求分位数
x=df['数学'].quantile(0.35)
print(df[df['数学']<x])
数据格式化:
df.round(2)设置小数点位数
print(df.round({'a1':1}))对指定列进行保留
df3=df.applymap(lambda x:'{:.2f}'.format(x))#使用自定义函数实现保留小数位置
#百分比
df['百分比']=df['A1'].apply(lambda x:format(x,'.0%'))
#设置千位分隔符
df['买家支付']=df['买家支付'].apply(lambda x:format(int(x),','))
数据分组
#按照一列分组统计
df1=df[['名称','数量','单价']]
print(df1.groupby('名称').sum())
#按照多列进行分组
print(df1.groupby(['名称','销售员']).sum())
#分组并按照指定列进行计算
for name,group in df1.groupby('名称'):
print(name)
print(group)
ptint('-----')
#多列进行分组
for (k1,k2),group in df1.groupby(['名称','销售员']):
print(k1,k2)
print(group)
ptint('-----')
#先分组后求和
print(df1.groupby('产品名称').agg(['sum','mean']))
#对不同列采用不同的聚合函数
print(df1.groupby('产品名称').agg({'数量':['sum','mean'],'成交额':['max']}))
#利用字典进行分组
df=df.set_index('商品名称')#设置商品名称为行索引
dict1={'bh':'hb'}
df1=df.groupby(dict1,axis=1).sum()
print(df1)
#根据Series对象进行分组统计
s=pd.Series(dict1)
数据移位
df['销量差']=df['oppo']-df['oppo'].shift()
数据转换
new_df=df['快递地址'].str.split('',expand=True)
df['省']=new_df[0]
df['市']=new_df[1]
df['区']=new_df[2]#将一列数据转化为多列数据
#将元组数据进行分割
df=df.DataFrame(data=data)
print(df)
df=df.join(df['b'].apply(pd.
Series))
#行列转换,将列索引转为行
df=df.set_index(['班级','序号'])
df=df.stack()
#行列转换
df.unstack()
#指定列和行索引
print(df.pivot(index='序号',columns='班级',values='得分'))
#将DataFrame转换成列表
lst=df['产品名称'].tolist()
#将DataFrame转换成元组
t=[tuple(x) for x in df1.values]
for item in t:
print(item)
数据合并
相同的列进行合并
new_df=pd.merge(df1,df2,on='编号')
通过索引列进行合并数据
new_df=pd.merge(df1,df2,left_index=True,right_index=True,on='编号')
内连接
new_df=pd.merge(df1,df2,how='outer',on='编号')外连接
使用concat方法,数据合并(表结构相同,首尾相连)
df=pd.concat([df1,df2,df3],keys=['表1','表2','表3'])
使用concat横向表连接方式
df=pd.concat([df1,df2],axis=1)
数据导出
df.to_excel('导出信息表.xlsx',index=False)
导入到多个sheet中
work=pd.ExcelWriter('~.xlsx')
df.to_excel(work,sheet_name='学生成绩',index=False)
df[['姓名','总成绩']].to_excel(work,sheet_name='成绩表',index=False)
work.save()
导出csv文件
df.csv('学生成绩.csv',index=False,columns=['姓名','总成绩'],float_format='%.1f')
日期数据处理
将各种日期字符串转换成日期格式
df['转换后的日期']=pd.to_datatime(df['原日期'])
从多列组合成一个日期
df['组合后的日期']=pd.to_datetime(df)
#dt对象的使用
df['日期']=pd.to_datetime(df['原日期'])
df['年']=df['日期'].dt.year#提取年
df['星期几']=df['日期'].dt.day_name#提取星期
df['季度']=df['日期'].dt.quarter#提取季度
日期格式转换
显示数据用A,统计数据用AS![在这里插入图片描述](https://i-blog.csdnimg.cn/direct/9e0e5dfe28bf41c893a7277396533bb4.png#pic_center)