用Python的pandas框架操作Excel文件中的数据教程


Posted in Python onMarch 31, 2015

引言

本文的目的,是向您展示如何使用pandas 来执行一些常见的Excel任务。有些例子比较琐碎,但我觉得展示这些简单的东西与那些你可以在其他地方找到的复杂功能同等重要。作为额外的福利,我将会进行一些模糊字符串匹配,以此来展示一些小花样,以及展示pandas是如何利用完整的Python模块系统去做一些在Python中是简单,但在Excel中却很复杂的事情的。

有道理吧?让我们开始吧。
为某行添加求和项

我要介绍的第一项任务是把某几列相加然后添加一个总和栏。

首先我们将excel 数据 导入到pandas数据框架中。
 

import pandas as pd
import numpy as np
df = pd.read_excel("excel-comp-data.xlsx")
df.head()

用Python的pandas框架操作Excel文件中的数据教程

我们想要添加一个总和栏来显示Jan、Feb和Mar三个月的销售总额。

在Excel和pandas中这都是简单直接的。对于Excel,我在J列中添加了公式sum(G2:I2)。在Excel中看上去是这样的:

用Python的pandas框架操作Excel文件中的数据教程

下面,我们是这样在pandas中操作的:
 

df["total"] = df["Jan"] + df["Feb"] + df["Mar"]
df.head()

用Python的pandas框架操作Excel文件中的数据教程

接下来,让我们对各列计算一些汇总信息以及其他值。如下Excel表所示,我们要做这些工作:

用Python的pandas框架操作Excel文件中的数据教程

如你所见,我们在表示月份的列的第17行添加了SUM(G2:G16),来取得每月的总和。
进行在pandas中进行列级别的分析很简单。下面是一些例子:
 

df["Jan"].sum(), df["Jan"].mean(),df["Jan"].min(),df["Jan"].max()
 
(1462000, 97466.666666666672, 10000, 162000)

现在我们要把每月的总和相加得到它们的和。这里pandas和Excel有点不同。在Excel的单元格里把每个月的总和相加很简单。由于pandas需要维护整个DataFrame的完整性,所以需要一些额外的步骤。

首先,建立所有列的总和栏
 

sum_row=df[["Jan","Feb","Mar","total"]].sum()
sum_row
 
Jan   1462000
Feb   1507000
Mar    717000
total  3686000
dtype: int64

这很符合直觉,不过如果你希望将总和值显示为表格中的单独一行,你还需要做一些微调。

我们需要把数据进行变换,把这一系列数字转换为DataFrame,这样才能更加容易的把它合并进已经存在的数据中。T 函数可以让我们把按行排列的数据变换为按列排列。
 

df_sum=pd.DataFrame(data=sum_row).T
df_sum

用Python的pandas框架操作Excel文件中的数据教程

在计算总和之前我们要做的最后一件事情是添加丢失的列。我们使用reindex来帮助我们完成。技巧是添加全部的列然后让pandas去添加所有缺失的数据。
 

df_sum=df_sum.reindex(columns=df.columns)
df_sum

用Python的pandas框架操作Excel文件中的数据教程

现在我们已经有了一个格式良好的DataFrame,我们可以使用append来把它加入到已有的内容中。
 

df_final=df.append(df_sum,ignore_index=True)
df_final.tail()

用Python的pandas框架操作Excel文件中的数据教程

额外的数据变换

另外一个例子,让我们尝试给数据集添加状态的缩写。

对于Excel,最简单的方式是添加一个新的列,对州名使用vlookup函数并填充缩写栏。

我进行了这样的操作,下面是其结果的截图:

用Python的pandas框架操作Excel文件中的数据教程

你可以注意到,在进行了vlookup后,有一些数值并没有被正确的取得。这是因为我们拼错了一些州的名字。在Excel中处理这一问题是一个巨大的挑战(对于大型数据集而言)

幸运的是,使用pandas我们可以利用强大的python生态系统。考虑如何解决这类麻烦的数据问题,我考虑进行一些模糊文本匹配来决定正确的值。

幸运的是其他人已经做了很多这方面的工作。fuzzy wuzzy库包含一些非常有用的函数来解决这类问题。首先要确保你安装了他。

我们需要的另外一段代码是州名与其缩写的映射表。而不是亲自去输入它们,谷歌一下你就能找到这段代码code。

首先导入合适的fuzzywuzzy函数并且定义我们的州名映射表。
 

from fuzzywuzzy import fuzz
from fuzzywuzzy import process
state_to_code = {"VERMONT": "VT", "GEORGIA": "GA", "IOWA": "IA", "Armed Forces Pacific": "AP", "GUAM": "GU",
         "KANSAS": "KS", "FLORIDA": "FL", "AMERICAN SAMOA": "AS", "NORTH CAROLINA": "NC", "HAWAII": "HI",
         "NEW YORK": "NY", "CALIFORNIA": "CA", "ALABAMA": "AL", "IDAHO": "ID", "FEDERATED STATES OF MICRONESIA": "FM",
         "Armed Forces Americas": "AA", "DELAWARE": "DE", "ALASKA": "AK", "ILLINOIS": "IL",
         "Armed Forces Africa": "AE", "SOUTH DAKOTA": "SD", "CONNECTICUT": "CT", "MONTANA": "MT", "MASSACHUSETTS": "MA",
         "PUERTO RICO": "PR", "Armed Forces Canada": "AE", "NEW HAMPSHIRE": "NH", "MARYLAND": "MD", "NEW MEXICO": "NM",
         "MISSISSIPPI": "MS", "TENNESSEE": "TN", "PALAU": "PW", "COLORADO": "CO", "Armed Forces Middle East": "AE",
         "NEW JERSEY": "NJ", "UTAH": "UT", "MICHIGAN": "MI", "WEST VIRGINIA": "WV", "WASHINGTON": "WA",
         "MINNESOTA": "MN", "OREGON": "OR", "VIRGINIA": "VA", "VIRGIN ISLANDS": "VI", "MARSHALL ISLANDS": "MH",
         "WYOMING": "WY", "OHIO": "OH", "SOUTH CAROLINA": "SC", "INDIANA": "IN", "NEVADA": "NV", "LOUISIANA": "LA",
         "NORTHERN MARIANA ISLANDS": "MP", "NEBRASKA": "NE", "ARIZONA": "AZ", "WISCONSIN": "WI", "NORTH DAKOTA": "ND",
         "Armed Forces Europe": "AE", "PENNSYLVANIA": "PA", "OKLAHOMA": "OK", "KENTUCKY": "KY", "RHODE ISLAND": "RI",
         "DISTRICT OF COLUMBIA": "DC", "ARKANSAS": "AR", "MISSOURI": "MO", "TEXAS": "TX", "MAINE": "ME"}

这里有些介绍模糊文本匹配函数如何工作的例子。
 

process.extractOne("Minnesotta",choices=state_to_code.keys())
 
('MINNESOTA', 95)
 
process.extractOne("AlaBAMMazzz",choices=state_to_code.keys(),score_cutoff=80)

现在我知道它是如何工作的了,我们创建自己的函数来接受州名这一列的数据然后把他转换为一个有效的缩写。这里我们使用score_cutoff的值为80。你可以做一些调整,看看哪个值对你的数据来说比较好。你会注意到,返回值要么是一个有效的缩写,要么是一个np.nan 所以域中会有一些有效的值。
 

def convert_state(row):
  abbrev = process.extractOne(row["state"],choices=state_to_code.keys(),score_cutoff=80)
  if abbrev:
    return state_to_code[abbrev[0]]
  return np.nan

把这列添加到我们想要填充的单元格,然后用NaN填充它
 

df_final.insert(6, "abbrev", np.nan)
df_final.head()

用Python的pandas框架操作Excel文件中的数据教程

我们使用apply 来把缩写添加到合适的列中。
 

df_final['abbrev'] = df_final.apply(convert_state, axis=1)
df_final.tail()

用Python的pandas框架操作Excel文件中的数据教程

我觉的这很酷。我们已经开发出了一个非常简单的流程来智能的清理数据。显然,当你只有15行左右数据的时候这没什么了不起的。但是如果是15000行呢?在Excel中你就必须进行一些人工清理了。
分类汇总

在本文的最后一节中,让我们按州来做一些分类汇总(subtotal)。

在Excel中,我们会用subtotal 工具来完成。

用Python的pandas框架操作Excel文件中的数据教程

输出如下:

用Python的pandas框架操作Excel文件中的数据教程

在pandas中创建分类汇总,是使用groupby 来完成的。
 

df_sub=df_final[["abbrev","Jan","Feb","Mar","total"]].groupby('abbrev').sum()
df_sub

用Python的pandas框架操作Excel文件中的数据教程

然后,我们想要通过对data frame中所有的值使用 applymap 来把数据单位格式化为货币。
 

def money(x):
  return "${:,.0f}".format(x)
 
formatted_df = df_sub.applymap(money)
formatted_df

用Python的pandas框架操作Excel文件中的数据教程

格式化看上去进行的很顺利,现在我们可以像之前那样获取总和了。
 

sum_row=df_sub[["Jan","Feb","Mar","total"]].sum()
sum_row

 

Jan   1462000
Feb   1507000
Mar    717000
total  3686000
dtype: int64

把值变换为列然后进行格式化。
 

df_sub_sum=pd.DataFrame(data=sum_row).T
df_sub_sum=df_sub_sum.applymap(money)
df_sub_sum

用Python的pandas框架操作Excel文件中的数据教程

最后,把总和添加到DataFrame中。
 

final_table = formatted_df.append(df_sub_sum)
final_table

用Python的pandas框架操作Excel文件中的数据教程

你可以注意到总和行的索引号是‘0'。我们想要使用rename 来重命名它。
 

final_table = final_table.rename(index={0:"Total"})
final_table

用Python的pandas框架操作Excel文件中的数据教程

结论

到目前为止,大部分人都已经知道使用pandas可以对数据做很多复杂的操作——就如同Excel一样。因为我一直在学习pandas,但我发现我还是会尝试记忆我是如何在Excel中完成这些操作的而不是在pandas中。我意识到把它俩作对比似乎不是很公平——它们是完全不同的工具。但是,我希望能接触到哪些了解Excel并且想要学习一些可以满足分析他们数据需求的其他替代工具的那些人。我希望这些例子可以帮助到其他人,让他们有信心认为他们可以使用pandas来替换他们零碎复杂的Excel,进行数据操作。

Python 相关文章推荐
对于Python编程中一些重用与缩减的建议
Apr 14 Python
在主机商的共享服务器上部署Django站点的方法
Jul 22 Python
Python Requests 基础入门
Apr 07 Python
python验证码识别的实例详解
Sep 09 Python
python简易远程控制单线程版
Jun 20 Python
用Python读取几十万行文本数据
Dec 24 Python
使用Python的OpenCV模块识别滑动验证码的缺口(推荐)
May 10 Python
详解Django定时任务模块设计与实践
Jul 24 Python
Python搭建代理IP池实现获取IP的方法
Oct 27 Python
Django使用list对单个或者多个字段求values值实例
Mar 31 Python
在Ubuntu 20.04中安装Pycharm 2020.1的图文教程
Apr 30 Python
Python二元算术运算常用方法解析
Sep 15 Python
Python实现国外赌场热门游戏Craps(双骰子)
Mar 31 #Python
通过代码实例展示Python中列表生成式的用法
Mar 31 #Python
使用Python实现一个简单的项目监控
Mar 31 #Python
详解Python中内置的NotImplemented类型的用法
Mar 31 #Python
python计算N天之后日期的方法
Mar 31 #Python
使用Python3中的gettext模块翻译Python源码以支持多语言
Mar 31 #Python
python根据出生日期获得年龄的方法
Mar 31 #Python
You might like
PHP文件上传实例详解!!!
2007/01/02 PHP
PHP自定义函数实现格式化秒的方法
2016/09/14 PHP
PHP实现将几张照片拼接到一起的合成图片功能【便于整体打印输出】
2017/11/14 PHP
Laravel事件监听器用法实例分析
2019/03/12 PHP
Javascript & DHTML 实例编程(教程)(三)初级实例篇1—上传文件控件实例
2007/06/02 Javascript
js的匿名函数使用介绍
2013/12/11 Javascript
利用javascript数组长度循环数组内所有元素
2013/12/27 Javascript
jQuery中queue()方法用法实例
2014/12/29 Javascript
PhotoSwipe异步动态加载图片方法
2016/08/25 Javascript
jQuery选择器之子元素选择器详解
2017/09/18 jQuery
JavaScript实现计算多边形质心的方法示例
2018/01/31 Javascript
Material(包括Material Icon)在Angular2中的使用详解
2018/02/11 Javascript
vue中$refs的用法及作用详解
2018/04/24 Javascript
Vue中的v-for指令不起效果的解决方法
2018/09/27 Javascript
vue router 源码概览案例分析
2018/10/09 Javascript
vue2 v-model/v-text 中使用过滤器的方法示例
2019/05/09 Javascript
解决Vue在Tomcat8下部署页面不加载的问题
2019/11/12 Javascript
vue项目中锚点定位替代方式
2019/11/13 Javascript
通过实例了解Nodejs模块系统及require机制
2020/07/16 NodeJs
[06:50]DSPL次级职业联赛十强晋级之路
2014/11/18 DOTA
Python ORM框架SQLAlchemy学习笔记之数据添加和事务回滚介绍
2014/06/10 Python
通过Python使用saltstack生成服务器资产清单
2016/03/01 Python
Python使用matplotlib绘制正弦和余弦曲线的方法示例
2018/01/06 Python
pandas中的DataFrame按指定顺序输出所有列的方法
2018/04/10 Python
python和opencv实现抠图
2018/07/18 Python
django 基于中间件实现限制ip频繁访问过程详解
2019/07/30 Python
linux下python中文乱码解决方案详解
2019/08/28 Python
is_file和file_exists效率比较
2021/03/14 PHP
GANT英国官方网上商店:甘特衬衫
2018/02/06 全球购物
美味咖啡的顶级烘焙师:Cafe Britt
2018/03/15 全球购物
WebSphere面试题:在WebSphere里面如何部署一个应用
2015/08/02 面试题
应届大学生的推荐信
2013/11/20 职场文书
节水标语大全
2014/06/11 职场文书
自荐信格式模板
2015/03/27 职场文书
python中os.path.join()函数实例用法
2021/05/26 Python
AJAX引擎原理以及XmlHttpRequest对象的axios、fetch区别详解
2022/04/09 Javascript