「Python」Pandas-DataFrame的相关操作一
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()