办公自动化-Python操作Excel基本操作

  • excel基础了解

2007版本的Excel软件默认使用xlsx格式,2003版本默认使用xls格式。

xls格式文件使用了一种具有特定规律的二进制格式,其核心结构是Excel特有的复合文档类型结构。

xlsx文件与之不同,它的核心结构式XML数据集结构,相比于xls,xlsx结构更加清晰,相同数据占用空间更小。

xlrd读取Excel文件数据

xlrd读取Excel数据

import xlrd
book = xlrd.open_workbook('data/people.xls')

xlrd读取工作表数据

xlrd读取数据表第一个sheet方式

sheet = book.sheets()[0]
print(sheet)
Sheet  0:<Sheet1>
sheet = book.sheet_by_index(0) # 读取工作表时,通过下标读取
print(sheet)
Sheet  0:<Sheet1>
sheet = book.sheet_by_name('Sheet1') # 读取工作表时,通过表名读取
print(sheet)
Sheet  0:<Sheet1>

xlrd读取数据表sheet列表

sheets = book.sheets()
print(sheets)
[Sheet  0:<Sheet1>, Sheet  1:<Sheet2>, Sheet  2:<Sheet3>]

xlrd读取单元格数据

  • 方法

sheet.cell(row,col)

row 行

col 列

row 与 col下标都是从0开始
sheet.cell(0,1)
text:'city'
sheet.cell(1,0)
text:'张三'

xlwt将数据写入Excel文件

step1 创建xls文件对象

import xlwt
book = xlwt.Workbook()

step2 新建工作表

sheet = book.add_sheet('Sheet1')

step3 写入数据

sheet.write(0,0,'二两')

step4 保存为xls文件

book.save('data/people2.xls')

xlutils复制Excel

场景:

excel文件的工作表中本来就存在数据,追加数据

xlutils的copy方法可以将xlrd所属对象转为xlwt所属对象,从而实现直接修改工作表中已有数据。

使用copy方法直接复制

import xlrd
from xlutils.copy import copy
rd_book = xlrd.open_workbook('data/people.xls')

# 拷贝Book对象为Workbook对象
wt_book = copy(rd_book)
wt_sheet = wt_book.get_sheet(0)
wt_sheet.write(1,0,'修改内容')

# 另存为或覆盖
wt_book.save('data/people.xls')

使用openpyxl支持xlsx格式文件

  • 场景

xlwt只支持生成xls格式的Excel,无法将数据写入xlsx格式的excel文件中。

import openpyxl
# 创建工作簿对象
wb = openpyxl.Workbook()
# sheet工作簿对象
ws = wb.active
# 使用create_sheet()来创建一个新的worksheet
# 1表示所在的顺序
ws2 = wb.create_sheet('NewTitle',1)
# 第一行第一列
ws2.cell(row=1,column=1,value='First')
# 修改Title
wb.save('data/openpyxl_test.xlsx')

注意: 与xlrd、xlwt不同,openpyxl的下标是从1开始的

使用openpyxl读取数据

使用openpyxl读入数据并进行修改

import openpyxl
# 打开已有的xlsx文件
wb = openpyxl.load_workbook('data/openpyxl_test.xlsx')
# 返回该Excel文件所有的sheet
print(wb.sheetnames)
ws = wb['NewTitle']
# 改变标签栏颜色
ws.sheet_properties.tabColor = '99CCCC'
ws.cell(row=1,column=1,value='new first')
wb.save('data/openpyxl_test2.xlsx') # 另存为
wb.save('data/openpyxl_test.xlsx') # 覆盖保存
['Sheet', 'NewTitle']

字母列号与数字列号之间的转换

from openpyxl.utils import get_column_letter, column_index_from_string

# 根据列的数字返回字母
print(get_column_letter(2))  # B
# 根据字母返回列的数字
print(column_index_from_string('D'))  # 4
B
4

openpyxl修改工作表中的样式

import openpyxl
from openpyxl.styles import Font,colors,Alignment
# 创建Excel文件对象
wb = openpyxl.Workbook()
ws = wb.active
rows = [
    ['ID','name','age'],
    [1,'张三',28],
    [2,'李四',25],
    [3,'王五',40],
    [4,'赵六',23],
]

for row in rows:
    # 添加多行
    ws.append(row)
# 设置字体
font = Font(name='微软雅黑',size=25,italic=True,color=colors.BLACK,bold=True)
ws['A1'].font = font

ws['A1'].font = font
# 第5行行高,下标从1开始
ws.row_dimensions[5].height = 40
# A列列宽
ws.column_dimensions['A'].width = 30
# 合并单元格,在左上角写入数据即可
# 合并一行中的几个单元格
ws.merge_cells('A7:C7')
# 合并一个矩形区域中的单元格
ws.merge_cells('A9:C13')
ws['A9'] = '合并单元格'
wb.save('data/openpyxl_test3.xlsx')

使用openpyxl读取大批量数据

当我们处理特别大的Excel时,就需要使用openpyxl的只读(read_only)或只写(write_only),在只读或者只写模式下,openpyxl可以使用恒定内存来处理无限的数据,其原理就是先处理一部分,处理完成后,释放其内存,然后再读入部分数据进行处理

openpyxl读取具有100万条数据的Excel

from openpyxl import load_workbook
# read_only 设置为True
wb = load_workbook(filename = 'data/openpyxl_big.xlsx',read_only = True)
ws = wb['big_sheet']

for row in ws.rows:
    for cell in row:
        print(cell.value)
name
city
company
修改内容
北京
华胜
李四
上海
贝尔
王五
长沙
阿里
麻子
深圳
华为

**注意:**设置read_only为True,则开启只读模式

如何将100万条数据写入Excel

from openpyxl import Workbook
from openpyxl.cell import WriteOnlyCell
from openpyxl.comments import Comment
from openpyxl.styles import Font

# write_only 设置为True
wb = Workbook(write_only=True) # 设置write_only为True,则开启只写模式
ws = wb.create_sheet() # 只写模式下,不会包含任何工作表,要使用create_sheet()方法创建

cell = WriteOnlyCell(ws,value='只写状态下写入的内容')
cell.font = Font(name='微软雅黑',size = 36)
# 插入Excel批注
cell.comment = Comment(text='这是一个批注',author='二两') # 只写状态下,单元格想要具有样式或注释,请使用openpyxl.cell.WriteOnlyCell()
# 在只写工作簿中,只能使用append()
ws.append([cell,3.14,None]) # 只写模式下,只能使用append()不能在任意位置使用cell()或iter_rows()
wb.save('data/openpyxl_write_only_file.xlsx')

实战 - 使用 python 与 Excel 实现日历

解析:

插入文字并修改样式

为每个月建立一个sheet,然后将每个月的日期填入其中,这种重复性的操作必然要使用for或while

设置Excel底色

向Excel中插入图片

步骤:

1、 获得每月的日期并填入Excel中

2、修改单元格样式

3、修改部分Excel背景填充色

4、插入图片

使用calendar来获取日期

使用calender,calender是python中专门用于处理日历逻辑的内置库,使用非常方便

import calendar
calendar.monthcalendar(2023,10)
[[0, 0, 0, 0, 0, 0, 1],
 [2, 3, 4, 5, 6, 7, 8],
 [9, 10, 11, 12, 13, 14, 15],
 [16, 17, 18, 19, 20, 21, 22],
 [23, 24, 25, 26, 27, 28, 29],
 [30, 31, 0, 0, 0, 0, 0]]

三层for迭代完成日期获取与填充

# 一周的第一天,6表示星期日为一周的第一天,0表示星期一
calendar.setfirstweekday(firstweekday=6)

wb = openpyxl.Workbook()

for i in range(1,13): # 第一层迭代,遍历月份
    # 添加工作簿
    sheet = wb.create_sheet(index = 0 ,title = str(i) + '月')
    
    # 获取具体日期时间
    for j in range(len(calendar.monthcalendar(2023,i))): # 第二层迭代遍历周
        for k in range(len(calendar.monthcalendar(2023,i)[j])): # 第三层迭代遍历天,从而获得最终的日期
            value = calendar.monthcalendar(2023,i)[j][k]
            
            if value == 0:
                value = ''
                sheet.cell(row = j + 9 , column = k + 1 ).value = value
            else :
                sheet.cell(row = j + 9 , column = k + 1 ).value = value
                # 设置字体
                sheet.cell(row = j + 9 , column = k + 1 ).font = Font(u'微软雅黑',size=11)

修改单元格式,美化显示

# 单元格文字设置,右对齐,垂直居中
align = Alignment(horizontal='right',vertical='center')

# 添加星期几信息行
days = ['星期日','星期一','星期二','星期三','星期四','星期五','星期六',]
num = 0
for k3 in range(1,8): # (A~G)填写内容,设置列宽
    sheet.cell(row = 8 , column = k3 ).value = days[num]
    # 右对齐 + 居中
    sheet.cell(row = 8 , column = k3).alignment = align
    sheet.cell(row = 8 , column = k3).font = Font(u'微软雅黑',size = 11)
    
    # get_column_letter 数字转字母 get_column_letter(1) --> 'A'
    c_char = get_column_letter(k3)
    # 设置列宽
    sheet.column_dimensions[c_char].width = 12
    num += 1
    
for k4 in range(8,14):
    # 设置行高
    sheet.row_dimensions[k4].height = 30

修改部分Excel背景填充色

使用for迭代定位出单元格的位置,然后为其fill属性赋值就完成了单元格背景色的填充

from openpyxl.styles import  PatternFill
# 单元格填充色属性设置
fill = PatternFill('solid',fgColor='99CCCC')

# 对单元格进行颜色填充
for k1 in range(1,50):
    for k2 in range(1,50):
        sheet.cell(row=k1,column=k2).fill = fill
    

轻松向Excel中插入图片

直接使用add_image就可以向Excel中添加图片

from openpyxl.drawing.image import Image
# 添加图片
img = Image('data/1.png')
newsize = (490,490)
img.width,img.height = newsize
# 与顶部有些距离,好看一些
sheet.add_image(img,"I2")

保存工作簿

wb.save('data/openpyxl_rili.xlsx')

完整代码

########################################
# 三层for迭代完成日期获取与填充
########################################

# 一周的第一天,6表示星期日为一周的第一天,0表示星期一
calendar.setfirstweekday(firstweekday=6)

wb = openpyxl.Workbook()

for i in range(1,13): # 第一层迭代,遍历月份
    # 添加工作簿
    sheet = wb.create_sheet(index = 0 ,title = str(i) + '月')
    
    # 获取具体日期时间
    for j in range(len(calendar.monthcalendar(2023,i))): # 第二层迭代遍历周
        for k in range(len(calendar.monthcalendar(2023,i)[j])): # 第三层迭代遍历天,从而获得最终的日期
            value = calendar.monthcalendar(2023,i)[j][k]
            
            if value == 0:
                value = ''
                sheet.cell(row = j + 9 , column = k + 1 ).value = value
            else :
                sheet.cell(row = j + 9 , column = k + 1 ).value = value
                # 设置字体
                sheet.cell(row = j + 9 , column = k + 1 ).font = Font(u'微软雅黑',size=11)
                
    ########################################
    # 修改单元格式,美化显示
    ########################################
                
    # 单元格文字设置,右对齐,垂直居中
    align = Alignment(horizontal='right',vertical='center')

    # 添加星期几信息行
    days = ['星期日','星期一','星期二','星期三','星期四','星期五','星期六',]
    num = 0
    for k3 in range(1,8): # (A~G)填写内容,设置列宽
        sheet.cell(row = 8 , column = k3 ).value = days[num]
        # 右对齐 + 居中
        sheet.cell(row = 8 , column = k3).alignment = align
        sheet.cell(row = 8 , column = k3).font = Font(u'微软雅黑',size = 11)

        # get_column_letter 数字转字母 get_column_letter(1) --> 'A'
        c_char = get_column_letter(k3)
        # 设置列宽
        sheet.column_dimensions[c_char].width = 12
        num += 1

    for k4 in range(8,14):
        # 设置行高
        sheet.row_dimensions[k4].height = 30
        
    ########################################
    # 修改部分Excel背景填充色
    ########################################
        
    from openpyxl.styles import  PatternFill
    # 单元格填充色属性设置
    fill = PatternFill('solid',fgColor='99CCCC')

    # 对单元格进行颜色填充
    for k1 in range(1,50):
        for k2 in range(1,50):
            sheet.cell(row=k1,column=k2).fill = fill
            
    ########################################
    # 轻松向Excel中插入图片
    ########################################
    
    from openpyxl.drawing.image import Image
    # 添加图片
    img = Image('data/1.png')
    newsize = (490,490)
    img.width,img.height = newsize
    # 与顶部有些距离,好看一些
    sheet.add_image(img,"I2")
    
wb.save('data/openpyxl_rili.xlsx')

什么是Pandas

场景:

python 可以通过Excel中的数据自动做图

知识点:

  • pandas 是一个强大的分析结构化数据的工具集;它的使用基础是Numpy(提供高性能的矩阵运算);用于数据挖掘、数据分析和数据清洗功能等功能,因为Pandas操作Excel依赖于xlrd与xlwt,所以想要使用Pandas操作excel,需要先安装xlrd与xlwt

  • DataFrame类似于Excel中的一个工作表,它也有行与列的概念,pandas可以很方便的将Excel工作表与DataFrame相互转换

  • DataFrame 中的一行或一列其实就是Series,它类似于Excel工作表的一行或一列

Series 与 DataFrame

创建Series

import pandas as pd

s1 = pd.Series([1,2,3],index = [1,2,3], name = 'A')
print(s1)
1    1
2    2
3    3
Name: A, dtype: int64
s1.index
Index([1, 2, 3], dtype='int64')
s1.name
'A'
s1[1]
1

创建DataFrame

import pandas as pd
s1 = pd.Series([1,2,3],index = [1,2,3],name = 'A')
s2 = pd.Series([10,20,30],index = [1,2,3],name = 'B')
s3 = pd.Series([100,200,300],index = [1,2,3],name = 'C')
# 以list的形式,则会将s1,s2,s3当做行加入DF中,其中的name就是行号
df = pd.DataFrame([s1,s2,s3])
df
123
A123
B102030
C100200300
# 将s1,s2,s3当做列加入DF中,index作为行号
df2 = pd.DataFrame({s1.name: s1, s2.name: s2, s3.name: s3})
df2
ABC
1110100
2220200
3330300

Pandas 读写 Excel

Pandas 将数据写入Excel

import pandas as pd

# DataFrame 数据帧相当于 工作簿中的一个工作表
df = pd.DataFrame({
    'id':[1,2,3],
    'name':['张三','李四','王五'],
    'age':[28,25,30]
})

# 自定义索引,不然pandas会使用默认的索引,这会导致生成的工作表也会存在这些索引
df = df.set_index('id')
print(df)

df.to_excel('data/pandas_people.xlsx')
print('Done!')
   name  age
id          
1    张三   28
2    李四   25
3    王五   30
Done!

Pandas 数据读取Excel

读入时,设置不同的参数会有不同的效果

# header = 2 表示从第三行开始(从0开始),跳过了前两行,sheet_name 指定读取的工作表
people = pd.read_excel('data/pandas_people.xlsx',header=2,sheet_name = 'Sheet1')
# 输出列名
print(people.columns)
Index([2, '李四', 25], dtype='object')
# 如果读入的Excel中没有开头标题,则可以将header=None,人为的进行设置
people = pd.read_excel('data/pandas_people.xlsx',header=None)
people.columns = ['id','name','age']
print(people.columns)
Index(['id', 'name', 'age'], dtype='object')
# 指定Id列为索引
people = pd.read_excel('data/pandas_people.xlsx',index_col='id')
# 输出前5行,此时就不会产生默认索引了
print(people.head)
<bound method NDFrame.head of    name  age
id          
1    张三   28
2    李四   25
3    王五   30>
# skiprows开头跳过几行,usecols使用那些列中的数据,dtype设置某一列的类型
peoples = pd.read_excel('data/pandas_people.xlsx',skiprows=4,usecols='E:H',dtype={'ID':str,'gender':str,'birthday':str})

Pandas修改Excel数据

知识点:

如果dypte不设置,pandas遇到NaN数据就会将其转为float64,我们无法直接将其指定为整型,所以这里折中的先将其指定为str类型

通过at方法直接定位DataFrame中元素的位置,然后直接赋值修改

from datetime import datetime,date
startday = datetime.now()

import pandas as pd 

peoples = pd.read_excel('data/pandas_people1.xlsx',skiprows=4,usecols='B:D',
                       dtype={'ID':str,'gender':str,'birthday':str})

# 直接在DataFrame上操作
for i in peoples.index:
    peoples.at[i,'ID'] = i + 1
    peoples.at[i,'gender'] = 'Male' if i % 2 == 0 else 'Female'
    peoples.at[i,'birthday'] = date(startday.year + i,startday.month,startday.day)
    
print(peoples)

# inplace表示就地修改DataFrame,不必再重新创建一个新的DtaFrame来存储修改后的状态
peoples.set_index('ID',inplace=True)

peoples.to_excel('data/pandas_people2.xlsx')
   id name  age   ID  gender    birthday
0   1   张三   28  1.0    Male  2023-10-09
1   2   李四   25  2.0  Female  2024-10-09
2   3   王五   30  3.0    Male  2025-10-09

修改Excel中的数据

peoples = pd.read_excel('data/pandas_people.xlsx',index_col='id')
# 加工资
def add_1000(x):
    return x + 1000

# 1.直接对series相加
peoples['money'] = peoples['money'] + 1000
# 2.apply会逐个元素的去调用函数
peoples['money'] = peoples['money'].apply(add_1000)
# 3.通过匿名函数的方式
peoples['money'] = peoples['money'].apply(lambda x:x+1000)

peoples.to_excel('data/pandas_people3.xlsx')

Pandas排序Excel数据

对Excel排序对Pandas而言其实是对DataFrame排序,直接使用sort_values()方法就好

import pandas as pd

peoples = pd.read_excel('data/pandas_people3.xlsx',index_col = 'id')

# sort_values 安值排序,by针对哪一列
# ascending为False则从大到小
peoples.sort_values(by='money',inplace=True,ascending=False)
print(peoples)
   name  age  money
id                 
3    王五   30   3300
2    李四   25   3200
1    张三   28   3100

Pandas多列排序

import pandas as pd

peoples = pd.read_excel('data/pandas_people3.xlsx',index_col = 'id')

# 对多列进行排序,by与ascending都传入对应顺序的list,pandas会先对jake从小到大排序
# 这样no,就对不满意的人排在前面,方便开除他,然后对money排序,此时会在jake排序的基础上进行排序

peoples.sort_values(by=['age','money'],inplace=True,ascending=[True,False])
print(peoples)
   name  age  money
id                 
2    李四   25   3200
1    张三   28   3100
3    王五   30   3300

Pandas 过滤Excel数据

快速过滤Excel中不满足条件的数据

import pandas as pd

# 定义过滤方法
def age_50_to_90(a):
    return 50 <= a <=90

def level_a(s):
    return 40 <= s <= 100

students = pd.read_excel('data/pandas_people.xlsx',index_col = 'id')

# 使用DataFrame的loc(location)去定位出过滤后的数据
# 利用Series的apply去运用过滤方法,将数据进行过滤

students = students.loc[students['age'].apply(age_50_to_90)].loc[students['money'].apply(level_a)]

绘制柱状图与叠加柱状图

知识点:

matplotlib是一个python的包

用于绘制2D绘图,要绘制3D图像需要安装支持库

非常强大非常流行、有很多扩展

pandas + matplotlib绘制柱状图

import pandas as pd
import matplotlib.pyplot as plt

students = pd.read_excel('data/pandas_people.xlsx')
# sort_values排序,inplace原地修改,ascending False从小到大
students.sort_values(by='money',inplace=True,ascending=False)

# 直接使用plt.bar()绘制柱状图
plt.bar(students.name,students.money,color='orange')

# 设置标题、x轴名称与y轴名称,fontsize设置字号
plt.title('Student Money',fontsize = 16)
plt.xlabel('Name')
plt.ylabel('Money')

# 因为x轴字体太长,利用rotation将其旋转90度,方便显示
plt.xticks(students.name,rotation=90)
# 紧凑型布局(因为x轴文字比较长,为了让其显示全,使用紧凑型布局)
plt.tight_layout()
plt.show()
C:\Users\Administrator\AppData\Local\Temp\ipykernel_16600\2570441082.py:19: UserWarning: Glyph 29579 (\N{CJK UNIFIED IDEOGRAPH-738B}) missing from current font.
  plt.tight_layout()
C:\Users\Administrator\AppData\Local\Temp\ipykernel_16600\2570441082.py:19: UserWarning: Glyph 20116 (\N{CJK UNIFIED IDEOGRAPH-4E94}) missing from current font.
  plt.tight_layout()
C:\Users\Administrator\AppData\Local\Temp\ipykernel_16600\2570441082.py:19: UserWarning: Glyph 26446 (\N{CJK UNIFIED IDEOGRAPH-674E}) missing from current font.
  plt.tight_layout()
C:\Users\Administrator\AppData\Local\Temp\ipykernel_16600\2570441082.py:19: UserWarning: Glyph 22235 (\N{CJK UNIFIED IDEOGRAPH-56DB}) missing from current font.
  plt.tight_layout()
C:\Users\Administrator\AppData\Local\Temp\ipykernel_16600\2570441082.py:19: UserWarning: Glyph 24352 (\N{CJK UNIFIED IDEOGRAPH-5F20}) missing from current font.
  plt.tight_layout()
C:\Users\Administrator\AppData\Local\Temp\ipykernel_16600\2570441082.py:19: UserWarning: Glyph 19977 (\N{CJK UNIFIED IDEOGRAPH-4E09}) missing from current font.
  plt.tight_layout()
D:\Program Files\Anaconda3\lib\site-packages\IPython\core\pylabtools.py:152: UserWarning: Glyph 29579 (\N{CJK UNIFIED IDEOGRAPH-738B}) missing from current font.
  fig.canvas.print_figure(bytes_io, **kw)
D:\Program Files\Anaconda3\lib\site-packages\IPython\core\pylabtools.py:152: UserWarning: Glyph 20116 (\N{CJK UNIFIED IDEOGRAPH-4E94}) missing from current font.
  fig.canvas.print_figure(bytes_io, **kw)
D:\Program Files\Anaconda3\lib\site-packages\IPython\core\pylabtools.py:152: UserWarning: Glyph 26446 (\N{CJK UNIFIED IDEOGRAPH-674E}) missing from current font.
  fig.canvas.print_figure(bytes_io, **kw)
D:\Program Files\Anaconda3\lib\site-packages\IPython\core\pylabtools.py:152: UserWarning: Glyph 22235 (\N{CJK UNIFIED IDEOGRAPH-56DB}) missing from current font.
  fig.canvas.print_figure(bytes_io, **kw)
D:\Program Files\Anaconda3\lib\site-packages\IPython\core\pylabtools.py:152: UserWarning: Glyph 24352 (\N{CJK UNIFIED IDEOGRAPH-5F20}) missing from current font.
  fig.canvas.print_figure(bytes_io, **kw)
D:\Program Files\Anaconda3\lib\site-packages\IPython\core\pylabtools.py:152: UserWarning: Glyph 19977 (\N{CJK UNIFIED IDEOGRAPH-4E09}) missing from current font.
  fig.canvas.print_figure(bytes_io, **kw)

 

title、x轴以及y轴替换为中文显示

matplotlib默认字符集是不支持中文的,所以需要修改字符集

import pandas as pd
import matplotlib.pyplot as plt

students = pd.read_excel('data/pandas_people.xlsx')
# sort_values排序,inplace原地修改,ascending False从小到大
students.sort_values(by='money',inplace=True,ascending=False)

# 直接使用plt.bar()绘制柱状图
plt.bar(students.name,students.money,color='orange')

# 添加中文字体支持
from matplotlib.font_manager import FontProperties
# SimSun.ttc 简体字
font = FontProperties(fname=r'c:\windows\fonts\SimSun.ttc',size=16)

# 设置标题、x轴名称与y轴名称,fontsize设置字号
plt.title('Student Money',fontsize = 16,fontproperties=font)
plt.xlabel('Name',fontproperties=font)
plt.ylabel('Money',fontproperties=font)

# 因为x轴字体太长,利用rotation将其旋转90度,方便显示
plt.xticks(students.name,rotation=90)
# 紧凑型布局(因为x轴文字比较长,为了让其显示全,使用紧凑型布局)
plt.tight_layout()
plt.show()
C:\Users\Administrator\AppData\Local\Temp\ipykernel_16600\1332766611.py:24: UserWarning: Glyph 29579 (\N{CJK UNIFIED IDEOGRAPH-738B}) missing from current font.
  plt.tight_layout()
C:\Users\Administrator\AppData\Local\Temp\ipykernel_16600\1332766611.py:24: UserWarning: Glyph 20116 (\N{CJK UNIFIED IDEOGRAPH-4E94}) missing from current font.
  plt.tight_layout()
C:\Users\Administrator\AppData\Local\Temp\ipykernel_16600\1332766611.py:24: UserWarning: Glyph 26446 (\N{CJK UNIFIED IDEOGRAPH-674E}) missing from current font.
  plt.tight_layout()
C:\Users\Administrator\AppData\Local\Temp\ipykernel_16600\1332766611.py:24: UserWarning: Glyph 22235 (\N{CJK UNIFIED IDEOGRAPH-56DB}) missing from current font.
  plt.tight_layout()
C:\Users\Administrator\AppData\Local\Temp\ipykernel_16600\1332766611.py:24: UserWarning: Glyph 24352 (\N{CJK UNIFIED IDEOGRAPH-5F20}) missing from current font.
  plt.tight_layout()
C:\Users\Administrator\AppData\Local\Temp\ipykernel_16600\1332766611.py:24: UserWarning: Glyph 19977 (\N{CJK UNIFIED IDEOGRAPH-4E09}) missing from current font.
  plt.tight_layout()
D:\Program Files\Anaconda3\lib\site-packages\IPython\core\pylabtools.py:152: UserWarning: Glyph 29579 (\N{CJK UNIFIED IDEOGRAPH-738B}) missing from current font.
  fig.canvas.print_figure(bytes_io, **kw)
D:\Program Files\Anaconda3\lib\site-packages\IPython\core\pylabtools.py:152: UserWarning: Glyph 20116 (\N{CJK UNIFIED IDEOGRAPH-4E94}) missing from current font.
  fig.canvas.print_figure(bytes_io, **kw)
D:\Program Files\Anaconda3\lib\site-packages\IPython\core\pylabtools.py:152: UserWarning: Glyph 26446 (\N{CJK UNIFIED IDEOGRAPH-674E}) missing from current font.
  fig.canvas.print_figure(bytes_io, **kw)
D:\Program Files\Anaconda3\lib\site-packages\IPython\core\pylabtools.py:152: UserWarning: Glyph 22235 (\N{CJK UNIFIED IDEOGRAPH-56DB}) missing from current font.
  fig.canvas.print_figure(bytes_io, **kw)
D:\Program Files\Anaconda3\lib\site-packages\IPython\core\pylabtools.py:152: UserWarning: Glyph 24352 (\N{CJK UNIFIED IDEOGRAPH-5F20}) missing from current font.
  fig.canvas.print_figure(bytes_io, **kw)
D:\Program Files\Anaconda3\lib\site-packages\IPython\core\pylabtools.py:152: UserWarning: Glyph 19977 (\N{CJK UNIFIED IDEOGRAPH-4E09}) missing from current font.
  fig.canvas.print_figure(bytes_io, **kw)

绘制竖立的叠加柱状图

绘制竖立的叠加柱状图依旧使用bar()方法吗,只是多了stacked函数

import pandas as pd
import matplotlib.pyplot as plt

users = pd.read_excel('data/pandas_people.xlsx')

# 新计算出一个总量,用于排序
users['Total'] = users['Jan'] + users['Feb'] + users['Mar']
# 排序
users.sort_values(by='Total',inplace=True,ascending=False)

# 竖立的叠加柱状图,利用stacked就可以实现叠加形式
users.plot.bar(x='name',y=['Jan','Feb','Mar'],stacked=True)

# 紧凑型布局(因为x轴文字比较长,为了让其显示全,使用紧凑型布局)
plt.tight_layout()
plt.show()
C:\Users\Administrator\AppData\Local\Temp\ipykernel_16600\2459268171.py:15: UserWarning: Glyph 29579 (\N{CJK UNIFIED IDEOGRAPH-738B}) missing from current font.
  plt.tight_layout()
C:\Users\Administrator\AppData\Local\Temp\ipykernel_16600\2459268171.py:15: UserWarning: Glyph 20116 (\N{CJK UNIFIED IDEOGRAPH-4E94}) missing from current font.
  plt.tight_layout()
C:\Users\Administrator\AppData\Local\Temp\ipykernel_16600\2459268171.py:15: UserWarning: Glyph 26446 (\N{CJK UNIFIED IDEOGRAPH-674E}) missing from current font.
  plt.tight_layout()
C:\Users\Administrator\AppData\Local\Temp\ipykernel_16600\2459268171.py:15: UserWarning: Glyph 22235 (\N{CJK UNIFIED IDEOGRAPH-56DB}) missing from current font.
  plt.tight_layout()
C:\Users\Administrator\AppData\Local\Temp\ipykernel_16600\2459268171.py:15: UserWarning: Glyph 24352 (\N{CJK UNIFIED IDEOGRAPH-5F20}) missing from current font.
  plt.tight_layout()
C:\Users\Administrator\AppData\Local\Temp\ipykernel_16600\2459268171.py:15: UserWarning: Glyph 19977 (\N{CJK UNIFIED IDEOGRAPH-4E09}) missing from current font.
  plt.tight_layout()
D:\Program Files\Anaconda3\lib\site-packages\IPython\core\pylabtools.py:152: UserWarning: Glyph 29579 (\N{CJK UNIFIED IDEOGRAPH-738B}) missing from current font.
  fig.canvas.print_figure(bytes_io, **kw)
D:\Program Files\Anaconda3\lib\site-packages\IPython\core\pylabtools.py:152: UserWarning: Glyph 20116 (\N{CJK UNIFIED IDEOGRAPH-4E94}) missing from current font.
  fig.canvas.print_figure(bytes_io, **kw)
D:\Program Files\Anaconda3\lib\site-packages\IPython\core\pylabtools.py:152: UserWarning: Glyph 26446 (\N{CJK UNIFIED IDEOGRAPH-674E}) missing from current font.
  fig.canvas.print_figure(bytes_io, **kw)
D:\Program Files\Anaconda3\lib\site-packages\IPython\core\pylabtools.py:152: UserWarning: Glyph 22235 (\N{CJK UNIFIED IDEOGRAPH-56DB}) missing from current font.
  fig.canvas.print_figure(bytes_io, **kw)
D:\Program Files\Anaconda3\lib\site-packages\IPython\core\pylabtools.py:152: UserWarning: Glyph 24352 (\N{CJK UNIFIED IDEOGRAPH-5F20}) missing from current font.
  fig.canvas.print_figure(bytes_io, **kw)
D:\Program Files\Anaconda3\lib\site-packages\IPython\core\pylabtools.py:152: UserWarning: Glyph 19977 (\N{CJK UNIFIED IDEOGRAPH-4E09}) missing from current font.
  fig.canvas.print_figure(bytes_io, **kw)

绘制竖立的叠加柱状图

import pandas as pd
import matplotlib.pyplot as plt

users = pd.read_excel('data/pandas_people.xlsx')

# 新计算出一个总量,用于排序
users['Total'] = users['Jan'] + users['Feb'] + users['Mar']
# 排序
users.sort_values(by='Total',inplace=True,ascending=False)

# 水平的叠加柱状图,barh中的h表示horizontal水平的
# 使用stacked就可以实现叠加形式
users.plot.barh(x='name',y=['Jan','Feb','Mar'],stacked=True)

# 紧凑型布局(因为x轴文字比较长,为了让其显示全,使用紧凑型布局)
plt.tight_layout()
plt.show()
C:\Users\Administrator\AppData\Local\Temp\ipykernel_16600\1615121703.py:16: UserWarning: Glyph 29579 (\N{CJK UNIFIED IDEOGRAPH-738B}) missing from current font.
  plt.tight_layout()
C:\Users\Administrator\AppData\Local\Temp\ipykernel_16600\1615121703.py:16: UserWarning: Glyph 20116 (\N{CJK UNIFIED IDEOGRAPH-4E94}) missing from current font.
  plt.tight_layout()
C:\Users\Administrator\AppData\Local\Temp\ipykernel_16600\1615121703.py:16: UserWarning: Glyph 26446 (\N{CJK UNIFIED IDEOGRAPH-674E}) missing from current font.
  plt.tight_layout()
C:\Users\Administrator\AppData\Local\Temp\ipykernel_16600\1615121703.py:16: UserWarning: Glyph 22235 (\N{CJK UNIFIED IDEOGRAPH-56DB}) missing from current font.
  plt.tight_layout()
C:\Users\Administrator\AppData\Local\Temp\ipykernel_16600\1615121703.py:16: UserWarning: Glyph 24352 (\N{CJK UNIFIED IDEOGRAPH-5F20}) missing from current font.
  plt.tight_layout()
C:\Users\Administrator\AppData\Local\Temp\ipykernel_16600\1615121703.py:16: UserWarning: Glyph 19977 (\N{CJK UNIFIED IDEOGRAPH-4E09}) missing from current font.
  plt.tight_layout()
D:\Program Files\Anaconda3\lib\site-packages\IPython\core\pylabtools.py:152: UserWarning: Glyph 29579 (\N{CJK UNIFIED IDEOGRAPH-738B}) missing from current font.
  fig.canvas.print_figure(bytes_io, **kw)
D:\Program Files\Anaconda3\lib\site-packages\IPython\core\pylabtools.py:152: UserWarning: Glyph 20116 (\N{CJK UNIFIED IDEOGRAPH-4E94}) missing from current font.
  fig.canvas.print_figure(bytes_io, **kw)
D:\Program Files\Anaconda3\lib\site-packages\IPython\core\pylabtools.py:152: UserWarning: Glyph 26446 (\N{CJK UNIFIED IDEOGRAPH-674E}) missing from current font.
  fig.canvas.print_figure(bytes_io, **kw)
D:\Program Files\Anaconda3\lib\site-packages\IPython\core\pylabtools.py:152: UserWarning: Glyph 22235 (\N{CJK UNIFIED IDEOGRAPH-56DB}) missing from current font.
  fig.canvas.print_figure(bytes_io, **kw)
D:\Program Files\Anaconda3\lib\site-packages\IPython\core\pylabtools.py:152: UserWarning: Glyph 24352 (\N{CJK UNIFIED IDEOGRAPH-5F20}) missing from current font.
  fig.canvas.print_figure(bytes_io, **kw)
D:\Program Files\Anaconda3\lib\site-packages\IPython\core\pylabtools.py:152: UserWarning: Glyph 19977 (\N{CJK UNIFIED IDEOGRAPH-4E09}) missing from current font.
  fig.canvas.print_figure(bytes_io, **kw)

绘制饼图

import pandas as pd
import matplotlib.pyplot as plt

# 饼图会以索引作为饼图中每一块的显示标签,所以这里使用,index_col 指定索引
students = pd.read_excel('data/pandas_people4.xlsx',index_col='From')

# pie绘制饼图,饼图只需要使用一列数据,所以直接使用Series绘制则可
# counterclock为False,让饼图顺时针方式显示
# startangle起始位置,这样最大的部分就从-270度的位置开始绘制
students[2019].plot.pie(fontsize=8,counterclock=False,startangle=-270)
plt.title('title',fontsize=16,fontweight='bold')
plt.ylabel(2019,fontsize=12,fontweight='bold')
plt.show()

绘制折线图

import pandas as pd
import matplotlib.pyplot as plt

weeks = pd.read_excel('data/pandas_people5.xlsx',index_col='id')

# 绘制折线图,直接调用plot则可
weeks.plot(y=['age','Score'])
plt.title('Title',fontsize=16,fontweight='bold')
plt.xticks(weeks.index,fontsize=8)
plt.show()

绘制区域叠加折线图

import pandas as pd
import matplotlib.pyplot as plt

weeks = pd.read_excel('data/pandas_people5.xlsx',index_col = 'id')

# 绘制叠加折线图(获得当前时刻的最高点,并且知道每一部分做了多少贡献)
weeks.plot.area(y=['age','Score'])

plt.title('Title',fontsize = 16,fontweight='bold')
plt.xticks(weeks.index,fontsize=8)
plt.show()

注意: 

柱状图侧重于个体的描述,能准确的知道每个项目的大小。

饼状图侧重于描述在这个系统中,每个个体所占的权重。

折线图侧重于描述数据变化的趋势。

多表联合操作

场景:

利用Pandas 的多表联合操作可以轻松代替Excel中的vlookup功能,并且通过类似的方式,可以轻易实现跨文件的多表联合操作

使用DataFrame的merge()方法合并多表

语法:

all_df = students.marge(scores,how='left',on='ID',).fillna(0)

marge横向合并两个Dataframe

合并时students在left而scores在right,如果不指定how,那么合并时,students与socers就是取交集的效果,这里指定left,那么合并时,students中无论是否存在与socres对应的值都会保留

on用于设置合并的列,集students与socres以ID作为合并的列(两者都有ID这一列),如果students与socres中不存在相同名称的列,可以使用left_on = ID,right_on = ID ,这里因为都是叫ID,所以直接使用on=ID则可

import pandas as pd

students = pd.read_excel('data/students.xlsx',sheet_name = 'name')
scores = pd.read_excel('data/score.xlsx',sheet_name = 'score')

table = students.merge(scores,how='left',on='ID',).fillna(0)

table.分数 = table.分数.astype(int)
print(table)
   ID                    名称  分数
0   1      Samantha Montoya  83
1   2       Ivan Montgomery  23
2   3  Mr. Nathan Price DDS  66
3   4       Kelsey Andersen  90
4   5           Allen Smith   0
5   6      Richard Martinez  78
6   7        Mark Dominguez  71
7   8       William Leonard  86
8   9           Richard Roy  97
9  10           Craig Davis  43

合并时如果没有同名列 - 使用left_on 与 reight_on分别定义名称

# 读入时将ID设置为了index,此时列中就不存在ID了
students = pd.read_excel('data/students.xlsx',sheet_name='name',index_col = 'ID')
scores = pd.read_excel('data/score.xlsx',sheet_name = 'score',index_col='ID')

# 列中没有ID了,此时就无法使用on=ID,则使用left_on = students.index,right_on = scores.index的方式代替
table = students.merge(scores,how='left',left_on = students.index,right_on = scores.index).fillna(0)

table.分数 = table.分数.astype(int)
print(table)
   key_0                    名称  分数
0      1      Samantha Montoya  83
1      2       Ivan Montgomery  23
2      3  Mr. Nathan Price DDS  66
3      4       Kelsey Andersen  90
4      5           Allen Smith   0
5      6      Richard Martinez  78
6      7        Mark Dominguez  71
7      8       William Leonard  86
8      9           Richard Roy  97
9     10           Craig Davis  43

使用join()方法来合并DataFrame

语法:

all_df = students.join(scores,how='left',on='ID').fillna(0)

使用join 来进行横向拼接,join只有on方法,没有left_on 或right_on,join默认就是使用index来进行两个DataFrame的拼接,如果要非Index,就可以通过on去指定

# 读入时将ID设置为了index,此时列中就不存在ID了
students = pd.read_excel('data/students.xlsx',sheet_name='name',index_col = 'ID')
scores = pd.read_excel('data/score.xlsx',sheet_name = 'score',index_col='ID')

# 使用join来进行横向拼接,join只有on方法,没有left_on或right_on
# join默认就是使用index来进行两个DataFrame的拼接
# 如果要非index,可以通过On去指定
table = students.join(scores,how='left').fillna(0)
table.分数 = table.分数.astype(int)
print(table)
                      名称  分数
ID                          
1       Samantha Montoya  83
2        Ivan Montgomery  23
3   Mr. Nathan Price DDS  66
4        Kelsey Andersen  90
5            Allen Smith   0
6       Richard Martinez  78
7         Mark Dominguez  71
8        William Leonard  86
9            Richard Roy  97
10           Craig Davis  43

拆分数据

DataFrame拆分数据 - 类似表格中的数据分列

import pandas as pd 

names = pd.read_excel('data/students.xlsx',index_col='ID')
# print(names)
# 将完整名字拆分成姓氏与名字
df = names['名称'].str.split(expand=True)
names['First Name'] = df[0]
names['Last Name'] = df[1]
print(names)
                      名称 First Name   Last Name
ID                                             
1       Samantha Montoya   Samantha     Montoya
2        Ivan Montgomery       Ivan  Montgomery
3   Mr. Nathan Price DDS        Mr.      Nathan
4        Kelsey Andersen     Kelsey    Andersen
5            Allen Smith      Allen       Smith
6       Richard Martinez    Richard    Martinez
7         Mark Dominguez       Mark   Dominguez
8        William Leonard    William     Leonard
9            Richard Roy    Richard         Roy
10           Craig Davis      Craig       Davis

求和、求平均

知识点:

axis 为 1 将作用于每行中的所有列

axis 为 0 将作用于每列中的所有行

测试:

import pandas as pd

df = pd.DataFrame([[1,1,1,1],[2,2,2,2],[3,3,3,3],[4,4,4,4]],columns=['col1','col2','col3','col4'])
df
col1col2col3col4
01111
12222
23333
34444
# axis = 1  作用于行; mean对所选区域求平均数
df.mean(axis=1)
0    1.0
1    2.0
2    3.0
3    4.0
dtype: float64
# axis = 0  作用于列; mean对所选区域求平均数
df.mean(axis=0)
col1    2.5
col2    2.5
col3    2.5
col4    2.5
dtype: float64
# axis = 1 ; drop 删除区域 ; 删除每行的第4列
df.drop('col4',axis=1)
col1col2col3
0111
1222
2333
3444

实现求和与求平均

### import pandas as pd

students = pd.read_excel('data/pandas_people6.xlsx',index_col='ID')
# students
# 对每一行中的每一列进行求和操作
row_sum = students[['体重','身高']].sum(axis = 1)
# 对每一行的每一列进行求平均操作
row_mean = students[['体重','身高']].mean(axis = 1)

# 为DataFrame添加新的一列
students['Total'] = row_sum
students['Average'] = row_mean

# axis默认为0,对每一列中的每一行进行求平均操作
col_mean =  students[['体重','身高','Total','Average']].mean()
col_mean['名称'] = 'Summary'

# axis默认为0,对每一列中的每一行进行求平均操作
col_sum =  students[['体重','身高','Total','Average']].sum()
col_sum['名称'] = 'Sum'

# 通过append()方法添加新的一行,ignore_index忽略index
students = students._append(col_mean,ignore_index=True)
# 通过append()方法添加新的一行,ignore_index忽略index
students = students._append(col_sum,ignore_index=True)
print(students)
                      名称      体重      身高   Total  Average
0       Samantha Montoya   130.0   170.0   300.0    150.0
1        Ivan Montgomery   128.0   162.0   290.0    145.0
2   Mr. Nathan Price DDS   110.0   162.0   272.0    136.0
3        Kelsey Andersen    90.0   158.0   248.0    124.0
4            Allen Smith    88.0   154.0   242.0    121.0
5       Richard Martinez    89.0   154.0   243.0    121.5
6         Mark Dominguez   122.0   160.0   282.0    141.0
7        William Leonard   134.0   177.0   311.0    155.5
8            Richard Roy   150.0   178.0   328.0    164.0
9            Craig Davis   166.0   179.0   345.0    172.5
10        Jennifer Lewis   160.0   190.0   350.0    175.0
11    Jennifer Maldonado    92.0   160.0   252.0    126.0
12         David Johnson    99.0   162.0   261.0    130.5
13        Brittany Brown   100.0   169.0   269.0    134.5
14         Antonio Smith   123.0   170.0   293.0    146.5
15     Christopher Olsen   111.0   153.0   264.0    132.0
16        Joseph Webster   121.0   162.0   283.0    141.5
17         Heather Evans   109.0   170.0   279.0    139.5
18            David Pham   108.0   174.0   282.0    141.0
19         Amy Mcconnell    78.0   152.0   230.0    115.0
20               Summary   115.4   165.8   281.2    140.6
21                   Sum  2308.0  3316.0  5624.0   2812.0
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值