python数据分析三剑客之: pandas操作
pandas的操作
pandas的拼接操作
# pandas的拼接操作
级联 pd.concat , pd.append
合并 pd.merge , pd.join
一丶pd.concat()级联
# pandas使用pd.concat函数,与np.concatenate函数类似,只是多了一些参数:
# 参数说明:
objs
axis=0 # 方向 1 是 行, 0是 列
keys
join='outer' / 'inner':表示的是级联的方式,outer会将所有的项进行级联(忽略匹配和不匹配),而inner只会将匹配的项级联到一起,不匹配的不级联
ignore_index=False # 忽略索引
import pandas as pd
import numpy as np
from pandas import DataFrame,Series
# 准备数据
df1 = DataFrame(data=np.random.randint(0,100,size=(3,4)))
df2 = DataFrame(data=np.random.randint(0,100,size=(3,4)))
# 1. 匹配级联
pd.concat((df1,df2),axis=0) # 列
# 2.不匹配级联
# 不匹配指的是级联的维度的索引不一致。例如纵向级联时列索引不一致,横向级联时行索引不一致
# 两种连接方式:
# 外连接: 补充NaN 默认模式 outer
pd.concat((df1,df2),axis=0,join='outer') # 包含空值
# 内连接: 只连接匹配的项 inner
pd.concat((df1,df2),axis=0,join='inner') # inner 内连接(df1,和df2共有的列或行,空值行列剔除)
二丶pd.merge()合并
# 1.merge与concat的区别在于,merge需要依据某一共同的列来进行合并
# 2.使用pd.merge()合并时,会自动根据两者相同column名称的那一列,作为key来进行合并。
# 3.注意每一列元素的顺序不要求一致
# 参数:
how:out取并集 inner取交集
on:当有多列相同的时候,可以使用on来指定使用那一列进行合并,on的值为一个列表
# 1. 一对一合并
# 数据准备
df1 = DataFrame({'employee':['Bob','Jake','Lisa'],
'group':['Accounting','Engineering','Engineering'],
})
df2 = DataFrame({'employee':['Lisa','Bob','Jake'],
'hire_date':[2004,2008,2012],
})
# 合并 (employee是 合并条件)
pd.merge(df1,df2)
# 2. 多对一合并
df3 = DataFrame({
'employee':['Lisa','Jake'],
'group':['Accounting','Engineering'],
'hire_date':[2004,2016]})
df4 = DataFrame({'group':['Accounting','Engineering','Engineering'],
'supervisor':['Carly','Guido','Steve']
})
# 合并 (group 是合并条件)
pd.merge(df3,df4)
# 3. 多对多合并
df1 = DataFrame({'employee':['Bob','Jake','Lisa'],
'group':['Accounting','Engineering','Engineering']})
df5 = DataFrame({'group':['Engineering','Engineering','HR'],
'supervisor':['Carly','Guido','Steve']
})
# 合并 how指定合并的列
pd.merge(df1,df5,how='right')
# 4.key的规范化
# 1. 当列冲突时,即有多个列名称相同时,需要使用on=来指定哪一个列作为key,配合suffixes指定冲突列名,suffixes=自己指定后缀 (默认是x和y)
df1 = DataFrame({'employee':['Jack',"Summer","Steve"],
'group':['Accounting','Finance','Marketing']})
df2 = DataFrame({'employee':['Jack','Bob',"Jake"],
'hire_date':[2003,2009,2012],
'group':['Accounting','sell','ceo']})
# 合并
pd.merge(df1,df2,on='employee')
# 结果: group_x group_y hire_date
# 2. 当两张表没有可进行连接的列时,可使用left_on和right_on手动指定merge中左右两边的哪一列列作为连接的列
df5 = DataFrame({'name':['Lisa','Bobs','Bill'],
'hire_dates':[1998,2016,2007]})
# 合并
pd.merge(df1,df5,left_on='employee',right_on='name',how='outer')
#### 总结: 合并
### 内合并与外合并:out取并集 inner取交集
# 内合并:只保留两者都有的key(默认模式)
df6 = DataFrame({'name':['Peter','Paul','Mary'],
'food':['fish','beans','bread']}
)
df7 = DataFrame({'name':['Mary','Joseph'],
'drink':['wine','beer']})
# 外合并 how='outer':补NaN
df6 = DataFrame({'name':['Peter','Paul','Mary'],
'food':['fish','beans','bread']}
)
df7 = DataFrame({'name':['Mary','Joseph'],
'drink':['wine','beer']})
案例:人口分析
# coding: utf-8
# - 需求:
# - 导入文件,查看原始数据
# - 将人口数据和各州简称数据进行合并
# - 将合并的数据中重复的abbreviation列进行删除
# - 查看存在缺失数据的列
# - 找到有哪些state/region使得state的值为NaN,进行去重操作
# - 为找到的这些state/region的state项补上正确的值,从而去除掉state这一列的所有NaN
# - 合并各州面积数据areas
# - 我们会发现area(sq.mi)这一列有缺失数据,找出是哪些行
# - 去除含有缺失数据的行
# - 找出2010年的全民人口数据
# - 计算各州的人口密度
# - 排序,并找出人口密度最高的五个州 df.sort_values()
import numpy as np
from pandas import DataFrame,Series
import pandas as pd
# 读取数据
abb = pd.read_csv('./data/state-abbrevs.csv')
abb.head(2)
pop = pd.read_csv('./data/state-population.csv')
pop.head(2)
area = pd.read_csv('./data/state-areas.csv')
area.head(2)
### 数据合并
#将人口数据和各州简称数据进行合并
abb_pop = pd.merge(abb,pop,left_on='abbreviation',right_on='state/region',how='outer')
abb_pop.head(2)
#将合并的数据中重复的abbreviation列进行删除
abb_pop.drop(labels='abbreviation',axis=1,inplace=True)
abb_pop.head(2)
#查看存在缺失数据的列
abb_pop.isnull().any(axis=0)
### 一
# 找到有哪些state/region使得state的值为NaN,进行去重操作
#1.state列中哪些值为空
abb_pop['state'].isnull()
#2.可以将step1中空对应的行数据取出(state中的空值对应的行数据)
abb_pop.loc[abb_pop['state'].isnull()]
#3.将对应的行数据中指定的简称列取出
abb_pop.loc[abb_pop['state'].isnull()]['state/region'].unique()
### 二
#为找到的这些state/region的state项补上正确的值,从而去除掉state这一列的所有NaN
#1.先将USA对应的state列中的空值定位到
abb_pop['state/region'] == 'USA'
#2,将布尔值作为原数据的行索引,取出USA简称对应的行数据
abb_pop.loc[abb_pop['state/region'] == 'USA']
#3.获取符合要求行数据的行索引
indexs = abb_pop.loc[abb_pop['state/region'] == 'USA'].index
#4.将indexs这些行中的state列的值批量赋值成united states
abb_pop.loc[indexs,'state'] = 'United Status'
### 二
#将PR对应的state列中的空批量赋值成 PUERTO RICO
abb_pop['state/region'] == 'PR'
abb_pop.loc[abb_pop['state/region'] == 'PR']
indexs = abb_pop.loc[abb_pop['state/region'] == 'PR'].index
abb_pop.loc[indexs,'state'] = 'PUERTO RICO'
### 三
#合并各州面积数据areas
abb_pop_area = pd.merge(abb_pop,area,how='outer')
abb_pop_area.head(3)
### 四
#我们会发现area(sq.mi)这一列有缺失数据,找出是哪些行
abb_pop_area['area (sq. mi)'].isnull()
#将空值对应的行数据取出
indexs = abb_pop_area.loc[abb_pop_area['area (sq. mi)'].isnull()].index
#去除含有缺失数据的行
abb_pop_area.drop(labels=indexs,axis=0,inplace=True)
### 五
#找出2010年的全民人口数据
abb_pop_area.query('year == 2010 & ages == "total"')
### 六
#计算各州的人口密度
abb_pop_area['midu'] = abb_pop_area['population'] / abb_pop_area['area (sq. mi)']
abb_pop_area.head(2)
# 取前5条数据
abb_pop_area.sort_values(by='midu',axis=0,ascending=False).head(5)
三丶数据处理
删除重复的元素
# 使用duplicated()函数检测重复的行,返回元素为布尔类型的Series对象,每个元素对应一行,如果该行不是第一次出现,则元素为True
# - keep参数:指定保留哪一重复的行数据
# 使用drop_duplicates()函数删除重复的行
# drop_duplicates(keep='first/last'/False)
# 参数说明: first 保留第一行,last保留最后一行 ,False所有行
映射
# 1 . replace()函数:替换元素
# DataFrame替换操作
单值替换
普通替换: 替换所有符合要求的元素:to_replace=15,value='e'
按列指定单值替换: to_replace={列标签:替换值} value='value'
多值替换
列表替换: to_replace=[] value=[]
字典替换(推荐) to_replace={to_replace:value,to_replace:value}
# 把 6 替换成six
df.replace(to_replace=6,value='six')
# 字典的形式替换
df.replace(to_replace={6:'six'})
# to_replac 指定了某个元素进行替换
df.replace(to_replace={5:6},value='six')
# 2 . map函数:新建一列, map函数并不是df的方法,而是series的方法
# map()可以映射新一列数据
# map()中可以使用lambd表达式
# map()中可以使用方法,可以是自定义的方法
# eg:map({to_replace:value})
# 注意 map()中不能使用sum之类的函数,for循环
# 1. 新增一列:给df中,添加一列,该列的值为中文名对应的英文名
dic = {
'name':['张三','周杰伦','张三'],
'salary':[20000,10000,20000]
}
df = DataFrame(data=dic)
#映射关系表
dic = {
'张三':'tom',
'周杰伦':'jay'
}
df['e_name'] = df['name'].map(dic)
# 2.map当做一种运算工具,至于执行何种运算,是由map函数的参数决定的(参数:lambda,函数) def after_sal(s):
return s - (s-3000)*0.5
#超过3000部分的钱缴纳50%的税
df['after_sal'] = df['salary'].map(after_sal)
# applay() 方法和 map()具有相同的效果 , #apply效率高于map
df['after_sal'] = df['salary'].apply(after_sal) #apply效率高于map
# 注意:
# 并不是任何形式的函数都可以作为map的参数。只有当一个函数具有一个参数且有返回值,那么该函数才可以作为map的参数。
四丶使用聚合操作对数据异常值检测和过滤
### 使用df.std()函数可以求得DataFrame对象每一列的标准差
# 创建一个1000行3列的df 范围(0-1),求其每一列的标准差
df = DataFrame(data=np.random.random(size=(1000,3)),columns=['A','B','C'])
# 对df应用筛选条件,去除标准差太大的数据:假设过滤条件为 C列数据大于两倍的C列标准差
twice_std = df['C'].std() * 2
# ~ 取反 , loc[]对值进行过滤(标签索引)
df.loc[~(df['C'] > twice_std)]
# 总结:
# 检测过滤缺失值
dropna
fillna
# 检测过滤重复值
drop_duplicated(keep)
# 检测过滤异常值
得到鉴定异常值的条件
将异常值对应的行删除
# iloc 和 loc 的区别:
# 相同:
无论是iloc还是loc 均采用[]而不是括号
# 不同:
1. 如果只是取行 建议用iloc 因为比较简单
2. 如果列和行同时取 建议采用loc 因为可以直接定义到标签
3.iloc:位置索引,和列表索引类似,里面只能是数字
4.loc:标签索引,只能使用字符型标签来索引数据
五丶排序
### take()函数排序
# 接收一个索引列表,用数字表示,使得df根据列表中索引的顺序进行排序
# 栗子: eg:df.take([1,3,4,2,5])
# np.random.permutation()函数随机排序
np.random.permutation(1000)
#列排序,行排序
df.take(indices=np.random.permutation(1000),axis=0).take(indices=np.random.permutation(3),axis=1)
# np.random.permutation(x)可以生成x个从0-(x-1)的随机数列
df.take(indices=np.random.permutation(1000),axis=0).take(indices=np.random.permutation(3),axis=1)[0:5]
# 随机抽样
# 当DataFrame规模足够大时,直接使用np.random.permutation(x)函数,就配合take()函数实现随机抽样
六丶 数据分类处理【重点】
### 数据聚合是数据处理的最后一步,通常是要使每一个数组生成一个单一的数值。
# 数据分类处理:
# 1. 分组:先把数据分为几组
# 2. 用函数处理:为不同组的数据应用不同的函数以转换数据
# 3. 合并:把不同组得到的结果合并起来
# 数据分类处理的核心:
# 1. groupby()函数
# 2. groups属性查看分组情况
# 3. eg: df.groupby(by='item').groups
分组
### 分组
df = DataFrame({'item':['Apple','Banana','Orange','Banana','Orange','Apple'],
'price':[4,3,3,2.5,4,2],
'color':['red','yellow','yellow','green','green','green'],
'weight':[12,20,50,30,20,44]})
# 使用groupby实现分组
df.groupby(by='item',axis=0)
# 使用groups查看分组情况
# 该函数可以进行数据的分组,但是不显示分组情况
df.groupby(by='item',axis=0).groups
# 分组后的聚合操作:分组后的成员中可以被进行运算的值会进行运算,不能被运算的值不进行运算
#给df创建一个新列,内容为各个水果的平均价格
df.groupby(by='item',axis=0).mean()['price']
mean_price_series = df.groupby(by='item',axis=0)['price'].mean()
# 映射关系表
dic = mean_price_series.to_dict()
df['mean_price'] = df['item'].map(dic)
# 汇总:将各种颜色水果的平均价格和df进行汇总
df['color_mean_price'] = df['color'].map(df.groupby(by='color')['price'].mean().to_dict())
高级数据聚合
### 使用groupby分组后,也可以使用transform和apply提供自定义函数实现更多的运算
# 1. df.groupby('item')['price'].sum() <==> df.groupby('item')['price'].apply(sum)
# 2. transform和apply都会进行运算,在transform或者apply中传入函数即可
# 3. transform和apply也可以传入一个lambda表达式
# 1. 按照水果类型分组,求出平均价格
df.groupby(by='item')['price'].mean()
# 2. 定义函数
def my_mean(s):
sum = 0
for i in s:
sum += i
return sum/len(s)
# transform 函数 和 apply函数 都可以调用自定义的而函数出理数据
# 3.使用apply函数求出水果的平均价格
df.groupby(by='item')['price'].apply(my_mean)
# 4. 使用transform函数求出水果的平均价格
df.groupby(by='item')['price'].transform(my_mean)
transform() 方法+自定义函数
transform() 方法+python内置方法
apply() 方法+自定义函数
案例:美国2012年总统候选人政治献金数据分析
# coding: utf-8
# # 美国2012年总统候选人政治献金数据分析
# 导入包
import numpy as np
import pandas as pd
from pandas import Series,DataFrame
# 方便大家操作,将月份和参选人以及所在政党进行定义
months = {'JAN' : 1, 'FEB' : 2, 'MAR' : 3, 'APR' : 4, 'MAY' : 5, 'JUN' : 6,
'JUL' : 7, 'AUG' : 8, 'SEP' : 9, 'OCT': 10, 'NOV': 11, 'DEC' : 12}
of_interest = ['Obama, Barack', 'Romney, Mitt', 'Santorum, Rick',
'Paul, Ron', 'Gingrich, Newt']
parties = {
'Bachmann, Michelle': 'Republican',
'Romney, Mitt': 'Republican',
'Obama, Barack': 'Democrat',
"Roemer, Charles E. 'Buddy' III": 'Reform',
'Pawlenty, Timothy': 'Republican',
'Johnson, Gary Earl': 'Libertarian',
'Paul, Ron': 'Republican',
'Santorum, Rick': 'Republican',
'Cain, Herman': 'Republican',
'Gingrich, Newt': 'Republican',
'McCotter, Thaddeus G': 'Republican',
'Huntsman, Jon': 'Republican',
'Perry, Rick': 'Republican'
}
df = pd.read_csv('./data/usa_election.txt')
df.head()
#新建一列各个候选人所在党派party
df['party'] = df['cand_nm'].map(parties)
df.head()
#party这一列中有哪些元素
df['party'].unique()
#统计party列中各个元素出现次数
df['party'].value_counts()
#查看各个党派收到的政治献金总数contb_receipt_amt
df.groupby(by='party')['contb_receipt_amt'].sum()
#查看每天各个党派收到的政治献金总数contb_receipt_amt
df.groupby(by=['contb_receipt_dt','party'])['contb_receipt_amt'].sum()
#将表中日期格式转换为'yyyy-mm-dd' day-m-y
def transformDate(d):
day,month,year = d.split('-')
month = months[month]
return '20'+year+'-'+str(month)+'-'+day
df['contb_receipt_dt'] = df['contb_receipt_dt'].map(transformDate)
df.head()
#查看老兵(捐献者职业)主要支持谁 :查看老兵们捐赠给谁的钱最多
#1.将老兵对应的行数据取出
df['contbr_occupation'] == 'DISABLED VETERAN'
old_bing = df.loc[df['contbr_occupation'] == 'DISABLED VETERAN']
#2.根据候选人分组
old_bing.groupby(by='cand_nm')['contb_receipt_amt'].sum()
df['contb_receipt_amt'].max()
#捐赠金额最大的人的职业以及捐献额 .通过query("查询条件来查找捐献人职业")
df.query('contb_receipt_amt == 1944042.43')
python数据分析三剑客之: pandas操作的更多相关文章
- Python数据分析入门之pandas基础总结
Pandas--"大熊猫"基础 Series Series: pandas的长枪(数据表中的一列或一行,观测向量,一维数组...) Series1 = pd.Series(np.r ...
- Python数据分析工具:Pandas之Series
Python数据分析工具:Pandas之Series Pandas概述Pandas是Python的一个数据分析包,该工具为解决数据分析任务而创建.Pandas纳入大量库和标准数据模型,提供高效的操作数 ...
- python数据分析三剑客之: Numpy
数据分析三剑客之: Numpy 一丶Numpy的使用 numpy 是Python语言的一个扩展程序库,支持大维度的数组和矩阵运算.也支持针对数组运算提供大量的数学函数库 创建ndarray # 1 ...
- 《Python 数据分析》笔记——pandas
Pandas pandas是一个流行的开源Python项目,其名称取panel data(面板数据)与Python data analysis(Python 数据分析)之意. pandas有两个重要的 ...
- Python 数据分析包:pandas 基础
pandas 是基于 Numpy 构建的含有更高级数据结构和工具的数据分析包 类似于 Numpy 的核心是 ndarray,pandas 也是围绕着 Series 和 DataFrame 两个核心数据 ...
- 快速学习 Python 数据分析包 之 pandas
最近在看时间序列分析的一些东西,中间普遍用到一个叫pandas的包,因此单独拿出时间来进行学习. 参见 pandas 官方文档 http://pandas.pydata.org/pandas-docs ...
- Python数据分析库之pandas,你该这么学!No.1
写这个系列背后的故事 咦,面试系列的把基础部分都写完啦,哈哈答,接下来要弄啥嘞~ pandas吧 外国人开发的 翻译成汉语叫 熊猫 厉害厉害,很接地气 一个基于numpy的库 干啥的? 做数据分析用的 ...
- python数据分析三剑客基础之matpoltlib初解
一.什么是matplotlib? python的底层绘图工具,主要做数据可视化图表,源自matplot. 二.为什么要学matplotlib? 1.它能将数据进行可视化,更直观的呈现出来 2.它能让数 ...
- python数据分析三剑客之: matplotlib绘图模块
matplotlib 一.Matplotlib基础知识 Matplotlib中的基本图表包括的元素 - x轴和y轴 axis 水平和垂直的轴线 - x轴和y轴刻度 tick 刻度标示坐标轴的分隔,包括 ...
随机推荐
- 安装glibc
wget http://ftp.gnu.org/gnu/glibc/glibc-2.23.tar.gztar -zxvf glibc-2.23.tar.gz cd glibc-2.23 mkdir b ...
- Python并发编程内容回顾
Python并发编程内容回顾 并发编程小结 目录 • 一.到底什么是线程?什么是进程? • 二.Python多线程情况下: • 三.Python多进程的情况下: • 四.为什么有这把GIL锁? • 五 ...
- flask实战-个人博客-表单
表单 下面我们来编写所有表单类,personalBlog中主要包含下面这些表单: 登录表单: 文章表单: 评论表单: 博客设置表单: 这里仅介绍登录表单.文章表单.分类表单和评论表单,其他的表单在实现 ...
- CSP 201812-2 小明放学
问题描述: 解题思路: 由于数据的量较大,需要使用long long来存储结果,否则会爆掉结果只能得到一部分的分 可以类比时钟,将红绿灯的变换当成时钟的运转,这样用模运算来断定红绿灯在到达时处于什么颜 ...
- split分割字符串返回字符串数组
<script type="text/javascript"> var str='liu jin yu'; var str1=str.split(' '); docum ...
- Code Chef May Challenge 2019题解
传送门 \(REDONE\) 贡献可以拆成\(X(Y+1)+Y\),那么一个数\(x\)的贡献对最终答案的贡献就是\(x(a_1+1)(a_2+1)...\),那么最终答案肯定是\(\sum\limi ...
- IEnumerable、IEnumerator接口(如何增加迭代器功能)
IEnumerable.IEnumerator接口封装了迭代器功能,有了它,我们不需要将内部集合暴露出去,外界只需要访问我的迭代器接口方法即可遍历数据. 在C#中,使用foreach语句来遍历集合.f ...
- Vue模板语法(二)
Vue模板语法(二) 样式绑定 class绑定 使用方式:v-bind:class="expression" expression的类型:字符串.数组.对象 1.2 style绑 ...
- IntelliJ IDEA 插件推荐
1.GenerateAllSetter 自动生成类set方法 2.GsonFormat 根据JSON创建实体 3.Lombok plugin 简化代码 4. .ignore 忽略git提交文件 5.A ...
- nginx虚拟机配置
#虚拟主机的配置server {#监听端口listen 80;#服务器域名server_name localhost;#网页的默认编码#charset koi8r;#访问该虚拟主机的日志位置#acce ...