人生苦短,我学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='行索引的名字')
非常简单,就不赘述了。
知识点三:神器筛选直接上我操练的代码吧。筛选方法第一种:通过索引筛选 filter函数In [1]:
import numpy as np
import pandas as pd
In [139]:
path=r'C:\Users\xiaobin\Desktop\练习.xlsx'
df=pd.read_excel(path,index_col=0)
df
Out[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: object
In [141]:
df.西瓜.filter(like=('李'))
Out[141]:
李四 144
李山 139
小李子 93
Name: 西瓜, dtype: object
In [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: bool
In [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 values
In [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: bool
In [159]:
df.地区.str.match('^..$')
Out[159]:
张三 True
李四 False
王二麻子 True
李山 False
小李子 True
曾贤志 False
黄山 True
级别 NaN
Name: 地区, dtype: object
上面是对列字段的处理,针对行字段的处理首先要把表格转置.T,
看一下数据,此次利用级别行来筛选
In [160]:
df
Out[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 |
编写排版太麻烦,不喜欢也别喷。