持续创作,加速成长!这是我参与「掘金日新计划 · 10 月更文挑战」的第5天, 点击查看活动详情
pandas是为解决数据分析任务而创建的
引入:
from pandas import Series,DataFrame
import pandas as pd
类型简介:
- Series: 一维数组,类似于Python中的基本数据结构list,区别是Series只允许存储相同的数据类型,这样可以更有效的使用内存,提高运算效率。就像数据库中的列数据;
- DataFrame: 二维的表格型数据结构。很多功能与R中的data.frame类似。可以将DataFrame理解为Series的容器;
- Panel:三维的数组,可以理解为DataFrame的容器。
1. Series
Series的创建
In [1]:obj=Series([4,7,-5,3])
In [2]:obj
Out[2]:
0 4
1 7
2 -5
3 3
'''
Series的交互式显示的字符串表示形式是索引在左边,值在右边。因为我们没有给数据指定索引,一个包含整数0到N-1这里N是数据的长度)的默认索引被创建。你可以分别的通过它的values和index属性来获取 Series的数组表示和索引对象:
'''
obj.values # [4,7,-5,3]) 获取值
obj.index # [0,1,2,3] 获取索引
指定Series的索引
# 创建series对象
obj2=Series([4,7,-5,3],index=['d','b','a','c'])
Out:
d 4
b 7
a -5
c 3
# 可以传进来字典然后创建series
In [7]:sdata={'Ohio':35000,'Texas':71000,'Oregon':16000,'Utah':5000}
In [8]:obj3=Series(sdata)
In [9]:obj3
Out[9]:
Ohio 35000
Texas 71000
Oregon 16000
Utah 5000
2. DataFrame
DataFrame既有行索引还有列索引,它有一组有序的列,每列既可以是不同类型(数值、字符串、布尔型)的数据,或者可以看做由Series组成的字典。
读取excel
data = pd.read_excel('1、第3章 数据整理与显示.xls',None)
# None表示一个文件中的多个表一起读取 sheet_name=1 取第一个表 skiprows=2 跳过的行数
sheets = data.keys() # 所有的表名
# 取出每一个表
sheet1_satisfication = data['满意度']
sheet2_wage = data['工资']
按照某一列分类汇总分组统计
目标:统计每个工资值有多少人
s2 = sheet2_wage.groupby('工资').count()
s2.columns = ['频数']
sheet1_satisfication.groupby(['代码','满意度']).count()
# 这里会有多重索引 df.index返回的是 [('xxx','xx')...]
第一个图为原始数据,第二个图为分类汇总后的结果
分组区间统计
目标:统计不同区间工资段的总人数
# 区间的下限
bins = [0,2500,4000,5500,7000,8500,10000,1000000]
# 区间段的标签
labels = ['2500以下','2500-4000','4000-5500','5500-7000','7000-8500','8500-10000','10000以上']
df2 = pd.cut(sheet2_wage['工资'],bins,right=False,labels=labels)
df2 = pd.DataFrame(df2.value_counts(sort=False))
# sort=False 防止2500以下跑到中间去.(buzhi
df2.columns = ['人数'] # 改变一下列名
df2.loc['总计'] = df2['人数'].agg('sum') # 将总计添加到最后一行
df2
bins的最大值是根据数据决定的,最后分类的结果:
一列中的3个不同值变为三列(0-1标签)
目标:将同一列的不同值转化为多列,并用0/1标签表示。
用例1:
这里实现的是:将产地的三种编码值(1,2,3)转化为三列
origin = dataset.pop('产地') # df.pop() 返回这一列并从df中删除
dataset['美国'] = (origin == 1) * 1.0
dataset['欧洲'] = (origin == 2) * 1.0
dataset['日本'] = (origin == 3) * 1.0
原始数据与实现效果如下:
用例2:将一个列中包含多种类别的,转化为多列,且变为0-1标签
目标效果:
实现代码:
import pandas as pd
df = pd.DataFrame({"适用场所":
["日常,约会,情趣,商务,party,旅行",
"日常,约会,party,运动,旅行",
"日常,约会,商务,party,旅行" ]})
from collections import Counter
# 通过逗号分割,并结合Counter将多种类划分为一个列表
data = pd.DataFrame(df.适用场所.str.split(",").apply(Counter).to_list())
# 没有该类别的就直接填充0
data = data.fillna(0).astype("int8")
# 最后统计一下该行有多少种类别
data["适用场所"] = data.sum(axis=1)
列转行
就是使用stack()
或者melt
函数实现。
目标效果
4种方法实现:
df = pd.DataFrame({'姓名': ['A','B','C'],
'英语':[90,60,70],
'数学':[80,98,80],
'语文':[85,90,75]})
# 方法1:
tmp=pd.melt(df,id_vars='姓名',var_name='科目',value_name='分数')
# 方法2:
tmp=df.set_index(['姓名']).stack().reset_index() # reset_index()重置索引
tmp.columns=['姓名','科目','分数']
# 方法3:
tmp=df.set_index(['姓名']).stack()
tmp.index.names=['姓名','科目']
tmp.reset_index(name='分数')
# 方法4:
tmp=df.set_index(['姓名']).stack()
tmp2=tmp.rename_axis(index=['姓名','科目'])
tmp2.name='分数'
tmp2.reset_index()
pd.melt()方法详解:
pd.melt()
frame: 需要处理的数据帧
id_vars: 不需要做列转行处理的字段,如果不设置该字段则默认会对所有列进行处理
value_vars: 需要做列转行的字段,不指定则不处理
var_name: 列转行处理后,生成字段列,对列转行之前的字段名称进行重命名
value_name: 列转行处理后,生成数值列,对列转行之前的数值进行命名
col_level: 指定具体的列名等级,通常在有多级列名时使用。
行转列
就是上一个列转行的方向效果。
目标效果:
![]()
三种方式实现:
unstack
或者df.pivot
# 方法一
df.pivot(index='姓名',columns='科目',values='分数').rename_axis(columns=None).reset_index()
# 方法二
tmp2=df.set_index(['姓名','科目'])['分数'].unstack()
# unstack是将多重索引形式的数据,转换为标准表格形式的数据
tmp2.rename_axis(columns=None).reset_index()
''' unstack()两个重要参数
level :要取消堆叠的索引级别,可以传递级别名称 。默认参数为-1,例子中为科目,即最后一个索引
fill_value :如果取消堆叠后有缺失数据,会以固定字符进行填充。
'''
# 方法三
df=tmp.set_index(['姓名','科目'])['分数'].unstack()
df.columns.name=None
df=df.reset_index()
还有些操作稍后更新嗷,敬请关注~🎉。希望对数据分析的朋友有些许的帮助