人生苦短,我学python!
python是目前最流行的编程语言,功能十分强大,在爬虫、数据分析、人工智能方面均得以广泛应用。本专辑主要分享两个数据分析库numpy和pandas在数据分析方面的基础知识和各种技能,pandas的快、准、简洁远非office的excel可比,而且免费。本期开始将全面总结pandas在处理excel数据的方方面面的知识,力争通过100期左右,完成pandas和numpy相关知识的介绍及其配套数据可视化库matplotlib和seaborn的介绍。特别说明,做这个专辑,纯属爱好,总结所学知识。pandas的强大,谁用谁知道,绝非打广告。我把她叫做超级excel。由于是笔记,当然就是先从非常厉害的东东开始了,所以没有依据由浅入深的顺序。知识的记录仍然按照知识点的方式进行,所有代码均经过反复实践,力争知识点没有错误。操作平台有Jupyter Notebook 、pycharm。安装非常简单。后期估计会记录一些他们的设置。本期共6547个字,需要花费17分钟阅读。本期是第一期,如果没人喜欢,下期开始就设置权限了,本来就是自己的学习小结,错误在所难免,对您有用就看看,没用就绕道,谢谢!建议电脑查看,手机查看格式可能会乱。
知识点一:批量打开多工作薄并快速进行合并具体步骤:
环境准备:
import pandas as pd
import os
第一步,新建文件夹(里需要合并的多个工作表)定义新建文件夹的路径;
imputdir = r'C:\Users\xiaobin\Desktop\111'
第一步,新建一个空的DateFrame;
dfe=pd.DataFrame(columns=['姓名','2011年','2012年','2013年','2014年'])
第三步:利用os库中的walk方法可以遍历文件夹的所有文件,并读取文件的名字,os.path.join能够将文件夹的路径和文件夹中的名字合并成每个文件完整路径。并将每个文件读取,再与空的DateFrame合并.
for parents,dirnames,filenames in os.walk(imputdir):
for filename in filenames:
df=pd.read_excel(os.path.join(parents,filename))
dfe=dfe.append(df,ignore_index=True)
第四歩:保存数据
df_empty.to_excel(r'C:\Users\xiaobin\Desktop\111\汇总表.xlsx',index_label='序号')

完整代码如下:
import pandas as pd
import os
imputdir = r'C:\Users\xiaobin\Desktop\111'
dfe=pd.DataFrame(columns=['姓名','2011年','2012年','2013年','2014年'])
for parents,dirnames,filenames in os.walk(imputdir):
for filename in filenames:
df=pd.read_excel(os.path.join(parents,filename))
dfe=dfe.append(df,ignore_index=True)
df_empty.to_excel(r'C:\Users\xiaobin\Desktop\111\汇总表.xlsx',index_label='序号')

环境安装:
import numpy as np
import pandas as pd
path='要保存的路径'
with pd.ExcelWriter(path) as writer:
df.to_excel(writer,sheet_name='第一个文件的名字',columns=['需要保存的列名,用逗号隔开'],index=True,index_label='行索引的名字')
df.to_excel(writer,sheet_name='第二个文件的名字',columns=['需要保存的列名,用逗号隔开'],index=True,index_label='行索引的名字')
df.to_excel(writer,sheet_name='第一个文件的名字',columns=['需要保存的列名,用逗号隔开'],index=True,index_label='行索引的名字')

非常简单,就不赘述了。

In [1]:
import numpy as npimport pandas as pdIn [139]:
path=r'C:\Users\xiaobin\Desktop\练习.xlsx'df=pd.read_excel(path,index_col=0)dfOut[139]:
| 西瓜 | 西红柿 | 苦瓜 | 南瓜 | 马铃署 | 地区 | |
|---|---|---|---|---|---|---|
| 张三 | 82 | 103 | 61 | 58 | 96 | 康定 |
| 李四 | 144 | 148 | 85 | 62 | 60 | 乌鲁木齐 |
| 王二麻子 | 121 | 73 | 142 | 56 | 145 | 常州 |
| 李山 | 139 | 119 | 120 | 86 | 94 | 石家庄 |
| 小李子 | 93 | 107 | 55 | 83 | 138 | 唐山 |
| 曾贤志 | 145 | 111 | 65 | 126 | 66 | 连云港 |
| 黄山 | 130 | 123 | 116 | 132 | 110 | 苏州 |
| 级别 | AA | A | B | AB | BB | NaN |
对序列进行筛选,针对Series的序列
In [140]:
df.西瓜.filter(items=['李四','李山'])Out[140]:
李四 144
李山 139
Name: 西瓜, dtype: objectIn [141]:
df.西瓜.filter(like=('李'))Out[141]:
李四 144
李山 139
小李子 93
Name: 西瓜, dtype: objectIn [142]:
df.西瓜.filter(regex=('^李.$'))Out[142]:
李四 144
李山 139
Name: 西瓜, dtype: object针对DateFrame的index(行索引)columns(列索引)
In [143]:
df.filter(items=['李四','李山'],axis=0) #行索引筛选axis=0,如果axis=1针对列筛选Out[143]:
| 西瓜 | 西红柿 | 苦瓜 | 南瓜 | 马铃署 | 地区 | |
|---|---|---|---|---|---|---|
| 李四 | 144 | 148 | 85 | 62 | 60 | 乌鲁木齐 |
| 李山 | 139 | 119 | 120 | 86 | 94 | 石家庄 |
In [144]:
df.filter(items=['李四','李山'],axis=1) #如果设置axis=1,啥都没有Out[144]:
| 张三 |
|---|
| 李四 |
| 王二麻子 |
| 李山 |
| 小李子 |
| 曾贤志 |
| 黄山 |
| 级别 |
In [145]:
df.filter(items=['西瓜','苦瓜'],axis=1) #对列索引进行筛选Out[145]:
| 西瓜 | 苦瓜 | |
|---|---|---|
| 张三 | 82 | 61 |
| 李四 | 144 | 85 |
| 王二麻子 | 121 | 142 |
| 李山 | 139 | 120 |
| 小李子 | 93 | 55 |
| 曾贤志 | 145 | 65 |
| 黄山 | 130 | 116 |
| 级别 | AA | B |
In [146]:
df.filter(items=['西瓜','苦瓜'],axis='columns')
#对列筛选columns
Out[146]:
| 西瓜 | 苦瓜 | |
|---|---|---|
| 张三 | 82 | 61 |
| 李四 | 144 | 85 |
| 王二麻子 | 121 | 142 |
| 李山 | 139 | 120 |
| 小李子 | 93 | 55 |
| 曾贤志 | 145 | 65 |
| 黄山 | 130 | 116 |
| 级别 | AA | B |
In [147]:
df.filter(items=['李四','李山'],axis='index') #行索引筛选axis='index',如果axis=1针对列筛选Out[147]:
| 西瓜 | 西红柿 | 苦瓜 | 南瓜 | 马铃署 | 地区 | |
|---|---|---|---|---|---|---|
| 李四 | 144 | 148 | 85 | 62 | 60 | 乌鲁木齐 |
| 李山 | 139 | 119 | 120 | 86 | 94 | 石家庄 |
In [148]:
df.filter(like='李',axis='index')Out[148]:
| 西瓜 | 西红柿 | 苦瓜 | 南瓜 | 马铃署 | 地区 | |
|---|---|---|---|---|---|---|
| 李四 | 144 | 148 | 85 | 62 | 60 | 乌鲁木齐 |
| 李山 | 139 | 119 | 120 | 86 | 94 | 石家庄 |
| 小李子 | 93 | 107 | 55 | 83 | 138 | 唐山 |
In [149]:
df.filter(like='瓜',axis='columns')
Out[149]:
| 西瓜 | 苦瓜 | 南瓜 | |
|---|---|---|---|
| 张三 | 82 | 61 | 58 |
| 李四 | 144 | 85 | 62 |
| 王二麻子 | 121 | 142 | 56 |
| 李山 | 139 | 120 | 86 |
| 小李子 | 93 | 55 | 83 |
| 曾贤志 | 145 | 65 | 126 |
| 黄山 | 130 | 116 | 132 |
| 级别 | AA | B | AB |
In [150]:
df.filter(regex='瓜',axis='columns')
Out[150]:
| 西瓜 | 苦瓜 | 南瓜 | |
|---|---|---|---|
| 张三 | 82 | 61 | 58 |
| 李四 | 144 | 85 | 62 |
| 王二麻子 | 121 | 142 | 56 |
| 李山 | 139 | 120 | 86 |
| 小李子 | 93 | 55 | 83 |
| 曾贤志 | 145 | 65 | 126 |
| 黄山 | 130 | 116 | 132 |
| 级别 | AA | B | AB |
In [151]:
df.filter(regex='^..$',axis='columns')Out[151]:
| 西瓜 | 苦瓜 | 南瓜 | 地区 | |
|---|---|---|---|---|
| 张三 | 82 | 61 | 58 | 康定 |
| 李四 | 144 | 85 | 62 | 乌鲁木齐 |
| 王二麻子 | 121 | 142 | 56 | 常州 |
| 李山 | 139 | 120 | 86 | 石家庄 |
| 小李子 | 93 | 55 | 83 | 唐山 |
| 曾贤志 | 145 | 65 | 126 | 连云港 |
| 黄山 | 130 | 116 | 132 | 苏州 |
| 级别 | AA | B | AB | NaN |
In [152]:
df.filter(regex='^..$',axis='index')Out[152]:
| 西瓜 | 西红柿 | 苦瓜 | 南瓜 | 马铃署 | 地区 | |
|---|---|---|---|---|---|---|
| 张三 | 82 | 103 | 61 | 58 | 96 | 康定 |
| 李四 | 144 | 148 | 85 | 62 | 60 | 乌鲁木齐 |
| 李山 | 139 | 119 | 120 | 86 | 94 | 石家庄 |
| 黄山 | 130 | 123 | 116 | 132 | 110 | 苏州 |
| 级别 | AA | A | B | AB | BB | NaN |
In [153]:
前面是针对Series和DateFrame的索引进行筛选,下面针对DateFrame的数据行和列进行筛选原理是针对序列Series的str.match方法 File "", line 1 前面是针对Series和DateFrame的索引进行筛选,下面针对DateFrame的数据行和列进行筛选 In [154]:
对 DataFrame 行或列进行筛选print('-----对 DataFrame 的正则筛选-------')print(df[df.地区.astype(str).str.match('^..$')])#对 df 的行筛选print(df.T[df.T.级别.astype(str).str.match('[AB]{2}')].T)#对 df 的列筛选In [155]:#筛选满足条件的某些列df.地区.str.match('^..$',na=False) #含义是筛选出地区中只有两个字的地区的对应行内容。Out[155]:
张三 True
李四 False
王二麻子 True
李山 False
小李子 True
曾贤志 False
黄山 True
级别 False
Name: 地区, dtype: boolIn [156]:
df[df.地区.str.match('^..$')] #此处出现错误主要是筛选字段地区中有错误值或者空值如何处理看下面,参数na=False就是屏蔽掉错误值。--------------------------------------------------------------------------ValueError Traceback (most recent call last) in ----> 1 df[df.地区.str.match('^..$')] #此处出现错误主要是筛选字段地区中有错误值或者空值如何处理看下面,参数na=False就是屏蔽调错误值d:\ProgramData\Anaconda3\lib\site-packages\pandas\core\frame.py in __getitem__(self, key) 2789 # Do we have a (boolean) 1d indexer?-> 2790 if com.is_bool_indexer(key): 2791 return self._getitem_bool_array(key) 2792 d:\ProgramData\Anaconda3\lib\site-packages\pandas\core\common.py in is_bool_indexer(key) 134 na_msg = "Cannot mask with non-boolean array containing NA / NaN values" 135 if isna(key).any():--> 136 raise ValueError(na_msg) 137 return False 138 return TrueValueError: Cannot mask with non-boolean array containing NA / NaN valuesIn [157]:
df[df.地区.str.match('^..$',na=False)] #看吧,正确了,不过还有其他方法处理错误值或者缺失值Out[157]:
| 西瓜 | 西红柿 | 苦瓜 | 南瓜 | 马铃署 | 地区 | |
|---|---|---|---|---|---|---|
| 张三 | 82 | 103 | 61 | 58 | 96 | 康定 |
| 王二麻子 | 121 | 73 | 142 | 56 | 145 | 常州 |
| 小李子 | 93 | 107 | 55 | 83 | 138 | 唐山 |
| 黄山 | 130 | 123 | 116 | 132 | 110 | 苏州 |
In [158]:
df.地区.astype(str).str.match('^..$')#两者对比看一下,空值转为字符串就变成false,放入索引中就不会被选择。Out[158]:
张三 True
李四 False
王二麻子 True
李山 False
小李子 True
曾贤志 False
黄山 True
级别 False
Name: 地区, dtype: boolIn [159]:
df.地区.str.match('^..$')Out[159]:
张三 True
李四 False
王二麻子 True
李山 False
小李子 True
曾贤志 False
黄山 True
级别 NaN
Name: 地区, dtype: object上面是对列字段的处理,针对行字段的处理首先要把表格转置.T,
看一下数据,此次利用级别行来筛选
In [160]:
dfOut[160]:
| 西瓜 | 西红柿 | 苦瓜 | 南瓜 | 马铃署 | 地区 | |
|---|---|---|---|---|---|---|
| 张三 | 82 | 103 | 61 | 58 | 96 | 康定 |
| 李四 | 144 | 148 | 85 | 62 | 60 | 乌鲁木齐 |
| 王二麻子 | 121 | 73 | 142 | 56 | 145 | 常州 |
| 李山 | 139 | 119 | 120 | 86 | 94 | 石家庄 |
| 小李子 | 93 | 107 | 55 | 83 | 138 | 唐山 |
| 曾贤志 | 145 | 111 | 65 | 126 | 66 | 连云港 |
| 黄山 | 130 | 123 | 116 | 132 | 110 | 苏州 |
| 级别 | AA | A | B | AB | BB | NaN |
In [161]:
df.T #第一步,表格转置Out[161]:
| 张三 | 李四 | 王二麻子 | 李山 | 小李子 | 曾贤志 | 黄山 | 级别 | |
|---|---|---|---|---|---|---|---|---|
| 西瓜 | 82 | 144 | 121 | 139 | 93 | 145 | 130 | AA |
| 西红柿 | 103 | 148 | 73 | 119 | 107 | 111 | 123 | A |
| 苦瓜 | 61 | 85 | 142 | 120 | 55 | 65 | 116 | B |
| 南瓜 | 58 | 62 | 56 | 86 | 83 | 126 | 132 | AB |
| 马铃署 | 96 | 60 | 145 | 94 | 138 | 66 | 110 | BB |
| 地区 | 康定 | 乌鲁木齐 | 常州 | 石家庄 | 唐山 | 连云港 | 苏州 | NaN |
In [162]:
df.values #df数据内容时ndarray,二维数组Out[162]:
array([[82, 103, 61, 58, 96, '康定'],
[144, 148, 85, 62, 60, '乌鲁木齐'],
[121, 73, 142, 56, 145, '常州'],
[139, 119, 120, 86, 94, '石家庄'],
[93, 107, 55, 83, 138, '唐山'],
[145, 111, 65, 126, 66, '连云港'],
[130, 123, 116, 132, 110, '苏州'],
['AA', 'A', 'B', 'AB', 'BB', nan]], dtype=object)In [163]:
df.T[df.T.级别.str.match('[AB]{2}',na=False)] #任务完成不过与原表不一致,咋整呢?Out[163]:
| 张三 | 李四 | 王二麻子 | 李山 | 小李子 | 曾贤志 | 黄山 | 级别 | |
|---|---|---|---|---|---|---|---|---|
| 西瓜 | 82 | 144 | 121 | 139 | 93 | 145 | 130 | AA |
| 南瓜 | 58 | 62 | 56 | 86 | 83 | 126 | 132 | AB |
| 马铃署 | 96 | 60 | 145 | 94 | 138 | 66 | 110 | BB |
In [164]:
df.T[df.T.级别.str.match('[AB]{2}',na=False)].T #再次进行转置Out[164]:
| 西瓜 | 南瓜 | 马铃署 | |
|---|---|---|---|
| 张三 | 82 | 58 | 96 |
| 李四 | 144 | 62 | 60 |
| 王二麻子 | 121 | 56 | 145 |
| 李山 | 139 | 86 | 94 |
| 小李子 | 93 | 83 | 138 |
| 曾贤志 | 145 | 126 | 66 |
| 黄山 | 130 | 132 | 110 |
| 级别 | AA | AB | BB |

编写排版太麻烦,不喜欢也别喷。