当前位置:   article > 正文

Python数据分析篇:pandas之Excel详解_python pandas excel

python pandas excel

一:简介

Pandas 是一个开源的第三方 Python 库,从 Numpy 和 Matplotlib 的基础上构建而来,享有数据分析“三剑客之一”的盛名(NumPyMatplotlibPandas)。提供了快速、灵活、明确的数据结构,旨在简单、直观地处理关系型、标记型数据。B站视频

pip install openpyxl

pip install pandas
# 使用阿里云镜像安装
pip install pandas -i https://mirrors.aliyun.com/pypi/simple/

# 引入模块,简写成pd(这是大家都采取不成文的习惯)
import pandas as pd
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8

二:数据结构

要学Pandas就必须要先了解Pandas的两大数据结构:Series 和 DataFrame。

2.1 Series 一维数据结构

在这里插入图片描述

  • Series类似于一维数组结构,用于表示一行数据或者一列数据。由索引index值values组成。
  • 可以通过list或者dict来构造Series。
  • 访问数据采用字典方式,通过[索引]来获取对应的数据。
  • Series 重写了算术运算符,如果数据是数字可以两个对象直接相加series1 + series2,对于索引相同的值可以做如加法运算,索引不相同的返回NaN(Not a Number)。
  • Series也提供了add()、sub()、mul()、div()等方法,提供了一些参数来设置,如fill_value表示默认填充值。

列表list构建

  • series.index:获取索引列对象
  • series.values:获取值列表
# 表示一列数据(第一列表示默认自带的索引从0开始),也可以通过参数index=[]自己设置索引
series1 = pd.Series(['张无忌', '孙悟空', '武大郎'])
print(series1)
0    张无忌
1    孙悟空
2    武大郎
dtype: object

# 武大郎
print(series1[2])
# index=keys(),RangeIndex(start=0, stop=3, step=1)
print(series1.index, series1.keys())

# ['张无忌' '孙悟空' '武大郎']
print(series1.values)

# 显式设置索引列
series1 = pd.Series(['张无忌', '孙悟空', '武大郎'], index=['a', 'b', 'c'])
print(series1)
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19

字典构建

series2 = pd.Series({'a': '张无忌', 'b': '孙悟空', 'c': '武大郎'})
print(series2)

a    张无忌
b    孙悟空
c    武大郎
dtype: object

# 武大郎
print(series2['c'])
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
series1 = pd.Series({'a': 1, 'b': 2, 'c': 3})
series2 = pd.Series({'a': 10, 'b': 20, 'c': 30, 'd': 40})
print(series1 + series2)

a    11.0
b    22.0
c    33.0
d     NaN
dtype: float64


# fill_value: 表示索引不存在按照默认值0算
add = series1.add(series2, fill_value=0)
print(add)
a    11.0
b    22.0
c    33.0
d    40.0
dtype: float64
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19

pd.Series(data, index, name)

2.2 DataFrame 二维数据结构

DataFrame类似于一个二维数组,可以看做成表格,由行和列组成。表格中的每一行每一列都是Series数据结构。
Series是由index索引➕values值组成。对于列index是指的列索引,对于行index是指的行索引(列名)。

在这里插入图片描述

# data: 每一行数据
# columns:列名
# index:自定义索引列,默认是数字从0开始,也可以显式指定
data = [('猛男', 30, '男'), ('舔狗', 50, '男'), ('细狗', 18, '男')]
df = pd.DataFrame(data, columns=('姓名', '年龄', '性别'))
print(df)

   姓名  年龄 性别
0  猛男  301  舔狗  502  细狗  18print(df['姓名'])
# 每一列也是<class 'pandas.core.series.Series'>
print(type(df['姓名']))


# 获取指定的行,没行也是一个Series ['猛男' 30 '男'] <class 'pandas.core.series.Series'>
print(df.loc[0].values, type(df.loc[0]))

# 行的index是列名
# Index(['姓名', '年龄', '性别'], dtype='object')
print(df.loc[0].index)
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23

Series作为行还是作为列主要取决于在构建DataFrame时是使用字典dict(列)还是列表list(行)。

作为列

# 方式一:value是list类型
# dtype指定列的数据类型,注意:只能统一指定,不能按照列来指定
df = pd.DataFrame({'姓名': ['猛男', '舔狗', '细狗'],
                   '年龄': [10, 20, 30],
                   '性别': ['男', '男', '男']},
                  index=[1, 2, 3],
                  dtype=str)

# 单独指定列的数据类型
df['姓名'] = df['姓名'].astype(str)
df['年龄'] = df['年龄'].astype(float)
df['性别'] = df['性别'].astype(str)                
print(df)

   姓名    年龄 性别
1  猛男  10.02  舔狗  20.03  细狗  30.0# 方式二:value是Series对象
# 作为列,index表示列索引,name就表示列名
c1 = pd.Series(['猛男', '舔狗', '细狗'], index=[1, 2, 3], name='姓名')
c2 = pd.Series([10, 20, 30], index=[1, 2, 3], name='年龄')
c3 = pd.Series(['男', '男', '男'], index=[1, 2, 3], name='性别')

df = pd.DataFrame({c1.name: c1, c2.name: c2, c3.name: c3})
print(df)

   姓名  年龄 性别
1  猛男  102  舔狗  203  细狗  30
  • 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
  • 32

作为行

# 作为行,index表示列名,name就表示列索引
header = ['姓名', '年龄', '性别']
r1 = pd.Series(['猛男', 10, '男'], index=header, name='a')
r2 = pd.Series(['舔狗', 20, '男'], index=header, name='b')
r3 = pd.Series(['细狗', 30, '男'], index=header, name='c')

df = pd.DataFrame([r1, r2, r3])
df.to_excel('temp.xlsx', index=False, header=False)
print(df)

   姓名  年龄 性别
a  猛男  30  男
b  舔狗  50  男
c  细狗  18
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14

三:DataFrame API

属性或方法描述
列索引操作
df.columnsdf.keys()获取表头列索引对象 Index(['姓名', '年龄'], dtype='object')
df.columns.values获取表头列索引对象的values列表 ['姓名' '年龄']
df.columns = ['Name', 'Age']重新设置表头
df.index获取所有列索引 RangeIndex(start=0, stop=3, step=1)
获取部分行
df.values获取所有列索引列表 [0 1 2]
df.values获取所有行数据,返回值类型<class ‘numpy.ndarray’> [[‘张三’, 20],[‘李四’, 25],[‘王五’, 30]]
len(df)获取数据行数(不算表头)
df.shape获取数据行数和列数tuple (3, 2) 3行2列
df.head(n)获取前n行数据,返回值类型DataFrame,n默认为5
df.tail(n)获取最后n行数据,返回值类型DataFrame,n默认为5
df.sample(n)随机获取n行数据,返回值类型DataFrame
获取指定行
df.loc[row_index]df.loc[1]:获取指定行的Series对象
df.loc[[row_index, row_index2]]df.loc[[1, 2]]:获取指定的多个行索引数据,返回值类型为 DataFrame
df.iloc[row_index]df.iloc[1]: 获取指定行的Series对象,和df.loc[row_index]结果一样
df.loc[df['列名'] == '列值']df.loc[df[‘姓名’] == ‘李四’] : 返回满足条件的行,返回值类型 DataFrame
df.loc[df['姓名'] == '李四'].loc[df['性别'] == '男']多个loc表示and关系
获取指定列
df['列名']df[‘姓名’] :获取指定列的数据,返回值类型 Series
df[['列名1', '列名2']]df[[‘姓名’, ‘年龄’]] : 获取多列数据,返回值类型 DataFrame
获取指定行指定列
df.loc[row_index, '列名']df.loc[1, ‘姓名’] :获取指定行指定列的单元格值,返回值str
df.loc[row_index, ['列名1', '列名2']]df.loc[1, [‘姓名’, ‘性别’]] : 获取某行的多列值,返回值类型 Series, df.loc[1, :] 返回指定行的所有列
df.at[row_index, '列名'] df.at[1, ‘姓名’] = df.loc[1, ‘姓名’] 获取指定指定列的值,返回值str,只是loc支持多列
df['列名'].at[row_index]df[‘姓名’].at[1] : 获取指定列的指定行的值,返回值str

columns:表头操作

import pandas as pd

df = pd.DataFrame([('张三', 20), ('李四', 25), ('王五', 30)], columns=('姓名', '年龄'))
# Index(['姓名', '年龄'], dtype='object')
print(df.columns, df.keys())

# ['姓名' '年龄']
print(df.columns.values)

# 重新设置表头
df.columns = ['Name', 'Age']
print(df)

  Name  Age
0   张三   20
1   李四   25
2   王五   30
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17

df.loc[df[‘列名’] == ‘列值’]:获取满足条件的行

df = pd.DataFrame([('张三', 20, '男'), ('李四', 25, '男'), ('王五', 30, '男')], 
	columns=('姓名', '年龄', '性别'))

print(df['姓名'] == '李四')
0    False
1     True
2    False
Name: 姓名, dtype: bool

# 返回值类型为<class 'pandas.core.series.Series'>
print(type(df['姓名'] == '李四'))
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
df = pd.DataFrame([('张三', 20, '男'), ('李四', 25, '男'), ('王五', 30, '男')], 
	columns=('姓名', '年龄', '性别'))
print(df.loc[df['姓名'] == '李四'])
   姓名  年龄 性别
1  李四  25# <class 'pandas.core.frame.DataFrame'>
print(type(df.loc[df['姓名'] == '李四']))

print(df.loc[df['姓名'] == '李四'].loc[df['性别'] == '男'])
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10

df.set_index(‘索引列名’, inplace=True) 指定索引列

pandas将索引列index数据列columns作为两个不同的概念来对待的。
df.set_index(“索引列名”, inplace=True):用于将某列作为索引列,inplace=True表示替换默认的索引列。

import pandas as pd

df = pd.DataFrame([(1, '张三', 20, '男'), (2, '李四', 25, '男'), (3, '王五', 30, '男')], 
                  columns=('id', '姓名', '年龄', '性别'))
print(df)
   id  姓名  年龄 性别
0   1  张三  201   2  李四  252   3  王五  30# 设置id为索引列,inplace=True表示替换默认的索引列
df.set_index('id', inplace=True)
print(df)
    姓名  年龄 性别
id           
1   张三  202   李四  253   王五  30# Int64Index([1, 2, 3], dtype='int64', name='id')
print(df.index)
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21

四:Excel读写

4.1 pd.ExcelFile(‘excel路径’):构建ExcelFile对象

file = pd.ExcelFile('订单.xlsx')
names = file.sheet_names
  • 1
  • 2

4.2 pd.ExcelWriter(‘文件路径’):构建ExcelWriter对象

4.3 pd.read_excel() -> dict[IntStrT, DataFrame]

  • io:excel文件路径。
  • sheet_name:list[IntStrT] 指定读取的sheet,默认为第一个,可以通过指定sheet的名字或者索引(从0开始),多个使用列表。
  • skiprows:跳过的行,从0开始。
  • header:指定表头实际的行索引。
  • index_col=‘ID’:设置索引列,设置后如果再写入pandas就不会再生成默认的索引列了。
  • dtype={‘ID’: str}:指定某些列的数据类型。注意:NaN的类型默认为float,NaN不能转换为int,可以变相的设置为str
  • 返回值类型:dict[IntStrT, DataFrame]:key表示sheet的索引,DataFrame表示每个Sheet对应的数据。

读取所有sheet的每行数据。

import pandas as pd
excel = pd.read_excel('订单.xlsx', sheet_name=[0, 1], skiprows=0)

for sheet, df in excel.items():
    for row in df.values:
        print(row)
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6

4.4 pd.read_csv():读取csv、tsv、txt文件

import pandas as pd

csv = pd.read_csv('test.csv', index_col='id')
tsv = pd.read_csv('test.tsv', sep='\t', index_col='id')
txt = pd.read_csv('test.txt', sep='|', index_col='id')
  • 1
  • 2
  • 3
  • 4
  • 5

4.5 pd.read_sql() : 从数据库中读取数据

import pandas as pd
import pymysql
import sqlalchemy

pymysql.install_as_MySQLdb()

sql = 'select id, username, gender from user'
conn = sqlalchemy.create_engine('mysql://root:root123@127.0.0.1:3306/test?charset=utf8')
user = pd.read_sql(sql, conn)
print(user)
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10

4.5 df.to_excel()

  • excel_writer:文件路径或者ExcelWriter
  • sheet_name:Sheet名称
  • index:第一列是否需要索引
  • header:是否指定表头bool,默认为True,当没有显式指定表头时使用列索引作为表头。

写入单个Sheet

import pandas as pd

header = ('姓名', '年龄')
rows = [('张三', 20), ('李四', 25)]
df = pd.DataFrame(rows, columns=header)
df.to_excel('test.xlsx', sheet_name='Sheet1', index=False)
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6

写入多个Sheet

import pandas as pd

header1 = ('姓名', '年龄')
rows1 = [('张三', 20), ('李四', 25)]
df = pd.DataFrame(rows1, columns=header1)

header2 = ('姓名', '年龄')
rows2 = [('虚竹', 20), ('梦姑', 25)]
df2 = pd.DataFrame(rows2, columns=header2)

writer = pd.ExcelWriter('test1.xlsx')
df.to_excel(writer, sheet_name='Sheet1', index=False)
df2.to_excel(writer, sheet_name='Sheet2', index=False)
writer.close()
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14

五:基本案例

行操作

import pandas as pd

sheet1 = pd.DataFrame([(1, '张三'), (2, '李四'), (3, '王五')], columns=('id', 'name'))
sheet2 = pd.DataFrame([(4, '赵六'), (5, '冯七')], columns=('id', 'name'))

# 追加Sheet drop=True 放弃旧的index
# users = sheet1.append(sheet2).reset_index(drop=True)
users = pd.concat([sheet1, sheet2]).reset_index(drop=True)

# 追加一行
user = pd.Series({'id': 6, 'name': '六六'})
users = users.append(user, ignore_index=True)

# 修改单元格数据
users.at[2, 'name'] = '隔壁老王'

# 整行替换
user = pd.Series({'id': 66, 'name': '六六'})
users.iloc[5] = user

# 插入一行
part1 = users[:3]
insert = pd.Series({'id': 99, 'name': '插队狗'})
part2 = users[3:]
users = part1.append(insert, ignore_index=True).append(part2).reset_index(drop=True)

# 删除多行 index也可以是range
users.drop(index=[0, 1], inplace=True)
# 通过切片删除
users.drop(index=users[3:5].index, inplace=True)

# 根据条件移除
where = users.loc[users['id'] == 3]
users.drop(index=where.index, inplace=True)
print(users)
  • 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
  • 32
  • 33
  • 34
  • 35

列操作

import pandas as pd
import numpy as np

sheet1 = pd.DataFrame([(1, '张三'), (2, '李四'), (3, '王五')], columns=('id', 'name'))
sheet2 = pd.DataFrame([(1, 10), (2, 20), (3, 30)], columns=('id', 'age'))

# 拼接列
all = pd.concat([sheet1, sheet2], axis=1)
print(all)

# 追加一列
sheet1['no'] = np.arange(1000, len(sheet1) + 1000)
# 删除列
sheet1.drop(columns=['name'], inplace=True)
# 插入一列
sheet1.insert(1, column='age', value=np.repeat(18, len(sheet1)))
# 重命名列名
sheet1.rename(columns={'id': 'ID', 'no': 'NO'}, inplace=True)

# 删除任意列种有NaN的行
sheet1.dropna(inplace=True)
print(sheet1)
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22

过滤

import pandas as pd

df = pd.DataFrame([(1, 10, 0.1), (2, 20, 0.2), (3, 15, 0.15)], columns=('id', 'price', 'discount'))
df.set_index('id', inplace=True)
df = df.loc[df['price'].apply(lambda x: 15 <= x <= 30)] \
	.loc[df['discount'].apply(lambda x: x > 0.15)]

# 简写形式:可以直接通过  df.price = df['price']
df = df.loc[df.price.apply(lambda x: 15 <= x <= 30)].loc[df.discount.apply(lambda x: x > 0.15)]
print(df)
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10

计算某列的值

计算某列的值:Series整列直接相乘。

import pandas as pd

df = pd.DataFrame([(1, 10, 0.1), (2, 20, 0.2)], columns=('id', 'price', 'discount'))
df.set_index('id', inplace=True)

# <class 'pandas.core.series.Series'>
# Python是可以对类进行计算符重写的,所以这里可以加减相乘等计算
print(type(df['price']))
df['amount'] = df['price'] * df['discount']
print(df)
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10

计算某列的值:单元格值 * 单元格值。这种方式可以对每一行做特殊处理。

import pandas as pd

df = pd.DataFrame([(1, 10, 0.1), (2, 20, 0.2)], columns=('id', 'price', 'discount'))
df.set_index('id', inplace=True)
for i in df.index:
    df.at[i, 'amount'] = df.at[i, 'price'] * df.at[i, 'discount']
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6

通过函数计算某列的值。

import pandas as pd

df = pd.DataFrame([(1, 10, 0.1), (2, 20, 0.2)], columns=('id', 'price', 'discount'))
df.set_index('id', inplace=True)
for i in df.index:
    # apply(函数名|匿名函数)
    df['amount'] = df['price'].apply(lambda x: x + 2)
print(df)
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8

复杂计算列

import pandas as pd


def calc(row):
    return (row['p1'] * 2 + row['p2'] * 3)/2 + row['id']

sheet1 = pd.DataFrame([(1, 20, 30), (2, 30, 40)], columns=('id', 'p1', 'p2'))
sheet1['p3'] = sheet1.apply(calc, axis=1)
print(sheet1)
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9

排序

import pandas as pd

df = pd.DataFrame([(1, 10, 0.1), (2, 20, 0.2), (3, 15, 0.15)], columns=('id', 'price', 'discount'))
df.set_index('id', inplace=True)

# inplace=True表示影响原来的df的值, ascending=True表示升续
# df.sort_values(by='price', inplace=True, ascending=True)

# 多个值排序:price asc, discount desc
df.sort_values(by=['price', 'discount'], inplace=True, ascending=[True, False])
print(df)
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11

统计每行的值和统计每列的值

import pandas as pd

# 每行求和、求平均值
df = pd.DataFrame([(1, '张三', 80, 90), (2, '李四', 70, 88), (3, '王五', 90, 98)], columns=('id', 'name', 'chinese', 'english'))
row = df[['chinese', 'english']]
df['sum'] = row.sum(axis=1)
df['avg'] = row.mean(axis=1)
print(df)

# 每列就平均值
col_avg = df[['chinese', 'english', 'sum', 'avg']].mean()
col_avg['id'] = ''
col_avg['name'] = 'summary'
new_df = df.append(col_avg, ignore_index=True)
print(new_df)
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15

合并和连接join

import pandas as pd

sheet1 = pd.DataFrame([(1, '张三'), (2, '李四'), (3, '王五')], columns=('id', 'name'))
sheet1.set_index('id', inplace=True)

sheet2 = pd.DataFrame([(1, 88), (2, 99)], columns=('id', 'score'))
sheet2.set_index('id', inplace=True)

# how: 表示连接方式, left/right/inner
# left_on:表示左表关联的字段,right_on表示右表关联的字段,on:表示左右两个表的关联字段相同
# 表示如果值为NaN就设置指定的值
# student_score = sheet1.merge(sheet2, how='left', on='id').fillna(0)
# student_score = sheet1.merge(sheet2, how='left', left_on='id', right_on='id').fillna(0)
# merge如果不设置on、left_on、right_on 会报错而join函数会自动识别每个sheet的index只作为关联字段
student_score = sheet1.merge(sheet2, how='left', left_on=sheet1.index, right_on=sheet2.index).fillna(0)
# 设置列的类型,数字默认是float
student_score.score = student_score.score.astype(int)
# print(student_score)

student_score2 = sheet1.join(sheet2, how='left').fillna(0)
student_score2.score = student_score2.score.astype(int)
print(student_score2)
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22

去除重复的行

import pandas as pd

# 去除重复行
df = pd.DataFrame([(1, '张三', 80, 90), (2, '李四', 70, 88), (3, '张三', 90, 98), (4, '张三', 90, 98)],
                  columns=('id', 'name', 'chinese', 'english'))
# 指定重复数据依据的字段, 如果重复可以选择留下first或者last
df.drop_duplicates(subset=['name'], inplace=True, keep='first')
print(df)
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8

获取重复的行

import pandas as pd

df = pd.DataFrame([(1, '张三', 80, 90), (2, '李四', 70, 88), (3, '张三', 90, 98), (4, '张三', 90, 98)],
                  columns=('id', 'name', 'chinese', 'english'))
# True表示重复
duplicated = df.duplicated(subset=['name'])
# 表示是否有True值
print(duplicated.any())
# 找出重复的行
duplicated = duplicated[duplicated==True]
print(df.iloc[duplicated.index])
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11

分组求和

import pandas as pd

df = pd.DataFrame([
    (1, '上海', '2021-03-01', 80), (2, '上海', '2022-05-01', 59),
    (3, '上海', '2022-07-01', 80), (4, '上海', '2022-08-01', 59),
    (5, '郑州', '2021-10-01', 50), (6, '郑州', '2021-10-01', 80),
    (7, '郑州', '2022-10-01', 30), (8, '郑州', '2022-10-01', 20)
],  columns=('id', 'city', 'date', 'score'))
# 添加一列
df['year'] = pd.DatetimeIndex(df['date']).year

groups = df.groupby(['city', 'year'])
sum = groups['score'].sum()
count = groups['id'].count()

pd2 = pd.DataFrame({'sum': sum, 'count': count})
print(pd2)
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17

填充列的值

在这里插入图片描述
在这里插入图片描述

import pandas as pd
from datetime import date, timedelta


def add_month(start_date, month):
    yd = month // 12
    m = start_date.month + month % 12
    if m != 12:
        yd += m // 12
        m = m % 12
    return date(start_date.year + yd, m, start_date.day)


books = pd.read_excel('book.xlsx', skiprows=3, usecols='C:F', dtype={'ID': str, 'InStore': str, 'Date': str})
start = date(2022, 10, 30)
for i in books.index:
    books['ID'].at[i] = i + 1
    books['InStore'].at[i] = 'Yes' if i % 2 == 0 else 'No'
    # 加天
    books.at[i, 'Date'] = start + timedelta(days=i)
    # 加年
    #books.at[i, 'Date'] = date(start.year + 1, start.month, start.day)
    # 加月
    #books.at[i, 'Date'] = add_month(start, i)
print(books)
books.set_index('ID', inplace=True)
books.to_excel('book2.xlsx')
  • 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

数据拆分

import pandas as pd

# 数据分列
df = pd.DataFrame([(1, '张 三'), (2, '李 四'), (3, '王 五')], columns=('id', 'name'))
tmp = df['name'].str.split(" ",expand=True)
# 列不存在则添加
df['first'] = tmp[0]
df['last'] = tmp[1]
print(df)
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9

校验数据的合法性

import pandas as pd


def check_age(row):
    if row.age < 0 or row.age > 150:
        print(f'{row.id} : {row.age} 数据非法')


pd = pd.DataFrame([(1, '张三', 30), (2, '李四', -1), (3, '王五', 1000)], columns=('id', 'name', 'age'))
# axis = 1: 表示从左到右(逐行校验)
# axis = 0: 表示从上到下(逐列校验)
pd.apply(check_age, axis=1)
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12

旋转

import pandas as pd

pd.options.display.max_columns = 999
df = pd.DataFrame([(1, '张三', 90), (2, '李四', 70), (3, '张三', 90)],
                  columns=('id', 'name', 'chinese'))
df.set_index('id', inplace=True)
transpose = df.transpose()
print(transpose)
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8

透视表分组求和

import pandas as pd
import numpy as np

df = pd.DataFrame([
    (1, '上海', '2021-03-01', 80), (2, '上海', '2022-05-01', 59),
    (3, '上海', '2022-07-01', 80), (4, '上海', '2022-08-01', 59),
    (5, '郑州', '2021-10-01', 50), (6, '郑州', '2021-10-01', 80),
    (7, '郑州', '2022-10-01', 30), (8, '郑州', '2022-10-01', 20)
],  columns=('id', 'city', 'date', 'score'))
# 添加一列
df['year'] = pd.DatetimeIndex(df['date']).year

table = df.pivot_table(columns='year', values='score', aggfunc=np.sum, index='city')
print(table)

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15

修改Sheet名称

from openpyxl import load_workbook
wb = load_workbook(file_path)
ws = wb['工作表1']
ws.title = '表1'
wb.save(file_path)
wb.close()

// 修改所有sheet名称, 重新读取再保存
file_path = 'test.xlsx'
file = pd.ExcelFile(file_path)
writer = pd.ExcelWriter(file_path)
for name in file.sheet_names:
    df = pd.read_excel(file_path, sheet_name=name)
    df.to_excel(excel_writer=writer, sheet_name=name + '2', header=False, index=False)
writer.save()
writer.close()


from openpyxl import load_workbook
wb = load_workbook(file_path)
sheetnames = wb.sheetnames
for sheetname in sheetnames:
    ws = wb[sheetname]
    ws.title = sheetname + '1'

wb.save(file_path)
wb.close()
  • 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

线性回归,数据预测

import pandas as pd
import matplotlib.pyplot as plt
from scipy.stats import linregress

# pip install matplotlib
# pip install scipy
df = pd.DataFrame([
    ('2022-01-01', 20), ('2022-02-01', 30), ('2022-03-01', 50),
    ('2022-04-01', 40), ('2022-05-01', 60), ('2022-06-01', 80),
    ('2022-07-01', 90), ('2022-08-01', 80), ('2022-09-01', 130),
    ('2022-10-01', 120), ('2022-11-01', 150), ('2022-12-01', 110)],
    columns=('month', 'amount'))

slope, intercept, r, p, std_err = linregress(df.index, df.amount)
exp = df.index * slope + intercept

# 预测值
print(slope * 35 + intercept)

plt.scatter(df.index, df.amount)
plt.plot(df.index, exp, color='orange')
plt.title(f'y={slope} * x + {intercept} ')
plt.xticks(df.index, df.month, rotation=90)
plt.tight_layout()
plt.show()
  • 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

条件格式

import pandas as pd

# 需要在jupyer环境下运行  jupyter notebook
def lowcolor(x):
    color = 'red' if x < 60 else 'black'
    return f'color:{color}'

def highcolor(col):
    return ['background-color:line' if s == col.max() else 'background-color:white' for s in col]

df = pd.DataFrame([
    ('张三', 20, 50, 70), ('李四', 80, 90, 90), ('王五', 40, 30, 80),
    ('赵六', 90, 80, 30), ('冯七', 70, 80, 50)],
    columns=('name', 'china', 'english', 'math'))

df.style.applymap(lowcolor, subset=['china', 'english']) \
    .applymap(highcolor, subset=['china', 'english'])

df.style.bar(color='green', subset=['math'])
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/AllinToyou/article/detail/614541
推荐阅读
相关标签
  

闽ICP备14008679号