用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中的条件判断语句基础学习教程
Feb 07 Python
Numpy数据类型转换astype,dtype的方法
Jun 09 Python
python微信公众号之关注公众号自动回复
Oct 25 Python
Python实现的栈、队列、文件目录遍历操作示例
May 06 Python
浅谈PySpark SQL 相关知识介绍
Jun 14 Python
如何利用Anaconda配置简单的Python环境
Jun 24 Python
Python 利用高德地图api实现经纬度与地址的批量转换
Aug 14 Python
使用Pandas将inf, nan转化成特定的值
Dec 19 Python
Python图像处理库PIL中图像格式转换的实现
Feb 26 Python
Python按照list dict key进行排序过程解析
Apr 04 Python
python中通过pip安装库文件时出现“EnvironmentError: [WinError 5] 拒绝访问”的问题及解决方案
Aug 11 Python
python用Configobj模块读取配置文件
Sep 26 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实现encode64编码类实例
2015/03/24 PHP
详解WordPress中分类函数wp_list_categories的使用
2016/01/04 PHP
PHP基于imagick扩展实现合成图片的两种方法【附imagick扩展下载】
2017/11/14 PHP
支持汉转拼和拼音分词的PHP中文工具类ChineseUtil
2018/02/23 PHP
PHP正则验证字符串是否为数字的两种方法并附常用正则
2019/02/27 PHP
PHP封装cURL工具类与应用示例
2019/07/01 PHP
thinkPHP3.2使用RBAC实现权限管理的实现
2019/08/27 PHP
javascript中利用数组实现的循环队列代码
2010/01/24 Javascript
Javascript公共脚本库系列(一): 弹出层脚本
2011/02/24 Javascript
window.onload和$(function(){})的区别介绍
2013/10/30 Javascript
jQuery实现简单的间隔向上滚动效果
2015/03/09 Javascript
js获取url传值的方法
2015/12/18 Javascript
JavaScript必知必会(三) String .的方法来自何方
2016/06/08 Javascript
Vue.js 2.0 和 React、Augular等其他前端框架大比拼
2016/10/08 Javascript
微信小程序 购物车简单实例
2016/10/24 Javascript
js中null与空字符串""的区别讲解
2019/01/17 Javascript
详解vue-element Tree树形控件填坑路
2019/03/26 Javascript
详解vue 在移动端体验上的优化解决方案
2019/05/20 Javascript
vue中使用elementUI组件手动上传图片功能
2019/12/13 Javascript
javascript 内存模型实例详解
2020/04/18 Javascript
Jquery使用each函数实现遍历及数组处理
2020/07/14 jQuery
Python3 操作符重载方法示例
2017/11/23 Python
Python使用Pickle模块进行数据保存和读取的讲解
2019/04/09 Python
详解pandas如何去掉、过滤数据集中的某些值或者某些行?
2019/05/15 Python
Python csv模块使用方法代码实例
2019/08/29 Python
Python爬虫库BeautifulSoup的介绍与简单使用实例
2020/01/25 Python
Python实现SMTP邮件发送
2020/06/16 Python
python接入支付宝的实例操作
2020/07/20 Python
英国在线定制百叶窗网站:Swift Direct Blinds
2020/02/25 全球购物
汽车销售员如何做职业生涯规划
2014/02/16 职场文书
机房搬迁方案
2014/05/01 职场文书
空气环保标语
2014/06/12 职场文书
秋季运动会演讲稿
2014/09/16 职场文书
群众路线教育实践活动个人对照检查材料思想汇报(社区班子)
2014/10/06 职场文书
2014年化工厂工作总结
2014/11/25 职场文书
交通事故起诉书
2015/05/19 职场文书