作者: 西魏陶渊明
博客: https://blog.springlearn.cn/
天下代码一大抄, 抄来抄去有提高, 看你会抄不会抄!
本系列文章还是引用之前的理念,阅读文章,你不需要记,只要知道这一篇在讲什么即可,收藏起来,用的时候过来抄代码。
本篇主要内容是案例演示与使用技巧一览, 目的让你轻松驾驭Pandas的强大功能。通过实例演示,深入了解各个分类下的核心方法,助你在数据分析领域脱颖而出。
系列文章:
- 第一篇:Pandas入门指南:掌握Python数据处理利器
- 第二篇:数据探索与清洗:使用Pandas轻松预处理数据
- 第三篇:深入了解Pandas数据结构:Series与DataFrame 【当前篇】
- 第四篇:数据选择与过滤:Pandas中的强大索引技巧
- 第五篇:数据操作与转换:学会利用Pandas处理复杂任务
文章目录
一、Series和DataFrame的区别
Series和DataFrame是Pandas库中两个重要的数据结构,它们之间有以下区别:
1.1 Series
Series是一维的标签化数组,类似于带有标签的一列数据。
Series具有自动分配的索引,可以通过索引标签访问和操作数据。
Series可以包含不同的数据类型,例如整数、浮点数、字符串等。
Series可以看作是具有标签索引的一维数组,类似于字典的结构。
1.2 DataFrame
DataFrame是一个二维的表格型数据结构,类似于电子表格或SQL中的表。
DataFrame由多个Series组成,每个Series代表一列数据。
DataFrame具有行和列的索引,可以通过索引标签或位置访问和操作数据。
DataFrame可以包含不同的数据类型,每列可以有不同的数据类型。
DataFrame提供了丰富的数据操作和处理功能,可以进行数据的切片、筛选、合并、聚合等操作。
总的来说,Series适用于处理一维数据,而DataFrame适用于处理二维表格型数据。DataFrame提供了更多的灵活性和功能,可以进行更复杂的数据处理和分析。无论是Series还是DataFrame,它们都是Pandas库中强大的数据结构,可以方便地进行数据操作和分析。
1.3 图示说明
如下代码就可以证明上面的结论。
import pandas as pd
import numpy as np
data = {
'角色': ['刘备', '关羽', '张飞', '赵云', '黄忠', '马超', '曹操', '孙权', '周瑜'],
'颜色': ['红色', '绿色', '蓝色', '', '红色', np.NAN, '蓝色', '黄色', '红色']
}
df = pd.DataFrame(data)
# <class 'pandas.core.frame.DataFrame'>
print(type(df))
# <class 'pandas.core.series.Series'>
print(type(df['角色']))
下面我们详细讲DataFrame的常用函数使用案例。
二、DataFrame
2.1 创建DataFrame的几种方式
2.1.1 从列表创建
import pandas as pd
data = [1, 2, 3, 4, 5]
# 先指定数据,在指定列
df = pd.DataFrame(data, columns=['Column1'])
2.1.2 从字典创建
import pandas as pd
data = {'Column1': [1, 2, 3, 4, 5],
'Column2': ['A', 'B', 'C', 'D', 'E']}
df = pd.DataFrame.from_dict(data)
2.1.3 从CSV文件读取
虽然参数支持这么多,实际上我们使用可能不会超过3个, 具体看下面代码示例。
参数 | 描述 |
---|---|
filepath_or_buffer | 文件路径、URL、文件对象或包含文件内容的字符串 |
sep | 分隔符,用于分隔字段的字符或字符串 |
delimiter | 分隔符,与sep 参数具有相同的功能 |
header | 指定作为列名的行索引 |
names | 指定列名的列表或数组 |
index_col | 指定作为行索引的列名或列索引 |
usecols | 指定要读取的列名或列索引 |
skiprows | 跳过指定的行数 |
nrows | 读取的行数 |
skipfooter | 跳过尾部的行数 |
parse_dates | 将指定的列解析为日期 |
date_parser | 指定用于解析日期的函数 |
dtype | 指定列的数据类型 |
na_values | 指定要识别为缺失值的值列表 |
keep_default_na | 是否保留默认的缺失值识别 |
converters | 指定要应用于列的转换器函数 |
true_values | 指定要识别为True的值列表 |
false_values | 指定要识别为False的值列表 |
skip_blank_lines | 是否跳过空行 |
comment | 注释标识符,跳过以该字符开始的行 |
thousands | 千位分隔符,用于解析数值 |
decimal | 小数点符号,用于解析数值 |
encoding | 文件编码的名称 |
engine | 指定要使用的解析引擎 |
import pandas as pd
df = pd.read_csv('data.csv')
2.1.4 从Excel文件读取
参数 | 描述 |
---|---|
io | 文件路径、ExcelFile对象、URL、Excel的二进制数据或缓冲区中的文件 |
sheet_name | 要读取的工作表名称或索引 |
header | 指定作为列名的行索引 |
index_col | 指定作为行索引的列名或列索引 |
usecols | 指定要读取的列名或列索引 |
skiprows | 跳过指定的行数 |
nrows | 读取的行数 |
skipfooter | 跳过尾部的行数 |
parse_dates | 将指定的列解析为日期 |
date_parser | 指定用于解析日期的函数 |
dtype | 指定列的数据类型 |
na_values | 指定要识别为缺失值的值列表 |
keep_default_na | 是否保留默认的缺失值识别 |
converters | 指定要应用于列的转换器函数 |
true_values | 指定要识别为True的值列表 |
false_values | 指定要识别为False的值列表 |
engine | 指定要使用的解析引擎 |
sheet | 用于指定要读取的工作表索引或名称的参数(已弃用) |
import pandas as pd
df = pd.read_excel('data.xlsx')
2.1.5 从Mydql数据库读取
import pandas as pd
import sqlite3
from sqlalchemy import create_engine
from sqlalchemy.orm import session
from sqlalchemy.orm import sessionmaker
import pyodbc
engine = create_engine("mssql+pyodbc://root:123456#@127.0.0.1:3306/auth?driver=SQL+Server",echo=True)
query = "SELECT * FROM user"
df = pd.read_sql(query, engine)
2.2 基本信息和查看数据
借助head()和tail()方法,快速预览DataFrame的前几行和后几行数据。
2.2.1 head()
head(): 查看DataFrame的前几行数据。
import pandas as pd
data = {'Column1': [1, 2, 3, 4, 5],
'Column2': ['A', 'B', 'C', 'D', 'E']}
df = pd.DataFrame(data)
#
# Column1 Column2
# 0 1 A
# 1 2 B
# 2 3 C
# 3 4 D
# 4 5 E
print(df)
# Column1 Column2
# 0 1 A
print(df.head(1))
2.2.2 tail()
tail(): 查看DataFrame的后几行数据。
import pandas as pd
data = {'Column1': [1, 2, 3, 4, 5],
'Column2': ['A', 'B', 'C', 'D', 'E']}
df = pd.DataFrame(data)
#
# Column1 Column2
# 0 1 A
# 1 2 B
# 2 3 C
# 3 4 D
# 4 5 E
print(df)
# Column1 Column2
# 4 5 E
print(df.tail(1))
2.2.3 info()
info(): 显示DataFrame的基本信息,包括列名、数据类型和非空值数量等。
# RangeIndex: 5 entries, 0 to 4
# Data columns (total 2 columns):
# # Column Non-Null Count Dtype
# --- ------ -------------- -----
# 0 Column1 5 non-null int64
# 1 Column2 5 non-null object
# dtypes: int64(1), object(1)
# memory usage: 208.0+ bytes
# None
print(df.info())
2.2.4 describe()
describe(): 统计DataFrame中数值列的基本统计信息,如计数、均值、标准差、最小值和最大值等。
# Column1
# count 5.000000
# mean 3.000000
# std 1.581139
# min 1.000000
# 25% 2.000000
# 50% 3.000000
# 75% 4.000000
# max 5.000000
print(df.describe())
2.2.5 shape()
shape: 返回DataFrame的形状(行数和列数)。
# (5, 2)
print(df.shape)
2.3 数据选择和筛选
索引操作:使用[]、.loc[]和.iloc[]等方式选择指定的行、列或元素。
2.3.1 loc
loc[]: 根据标签选择行和列。
# Column1 Column2
# 3 4 D
# 4 5 E
print(df.loc[3:4, ['Column1','Column2']])
2.3.2 iloc
iloc[]: 根据整数位置选择行和列。
# Column1 Column2
# 0 1 A
# 2 3 C
# 4 5 E
print(df.iloc[lambda x: x.index % 2 == 0])
# Column1 Column2
# 0 1 A
# 1 2 B
# 2 3 C
print(df.iloc[:3])
# Column1 Column2
# 0 1 A
print(df.iloc[[0]])
#
# Column1 1
# Column2 A
# Name: 0, dtype: object
print(df.iloc[0])
2.3.3 at
at[]: 根据标签获取单个元素。
获取指定索引下的, 某一列。
import pandas as pd
data = {'Name': ['John', 'Emily', 'Ryan'],
'Age': [25, 30, 35],
'City': ['New York', 'London', 'Paris']}
df = pd.DataFrame(data)
print(df)
# 使用at方法获取指定位置的元素
# Emily
name_value = df.at[1, 'Name']
# 35
age_value = df.at[2, 'Age']
2.3.4 iat
iat[]: 根据整数位置获取单个元素。
iat 和 at的区别在于iat只能使用索引找取数,而at可以指定名字。
import pandas as pd
# 创建一个示例DataFrame
data = {'A': [10, 20, 30, 40],
'B': [50, 60, 70, 80],
'C': [90, 100, 110, 120]}
df = pd.DataFrame(data)
# 使用iat方法获取指定位置的元素
print(df.iat[0, 0])
print(df.iat[2, 0])
# 打印修改后的DataFrame
print(df)
2.3.5 isin
isin(): 判断某列中的元素是否包含在给定的列表或数组中。
import pandas as pd
# 创建一个示例DataFrame
data = {'A': [10, 20, 30, 40],
'B': [50, 60, 70, 80],
'C': [90, 100, 110, 120]}
df = pd.DataFrame(data)
# 0 True
# 1 False
# 2 False
# 3 False
print(df['A'].isin([10]))
# 0 False
# 1 False
# 2 False
# 3 False
print(df['A'].isin([50]))
# 保留在指定数组中的数字,其他填充为0
# A B C
# 0 10.0 0.0 0.0
# 1 0.0 0.0 0.0
# 2 0.0 0.0 0.0
# 3 0.0 0.0 0.0
print(df[df.isin([10])].fillna(0))
2.4 数据清洗和处理
2.4.1 drop
drop(): 删除指定的行或列。
- axis = 1 是列
- axis = 0 是行
import pandas as pd
from pandas import DataFrame
# 创建一个示例DataFrame
data = {'A': [10, 20, 30, 40],
'B': [50, 60, 70, 80],
'C': [90, 100, 110, 120]}
df: DataFrame = pd.DataFrame(data)
# 删除A 列
# B C
# 0 50 90
# 1 60 100
# 2 70 110
# 3 80 120
print(df.drop('A', axis=1))
# 删除索引3行
# A B C
# 0 10 50 90
# 1 20 60 100
# 2 30 70 110
print(df.drop(3, axis=0))
2.4.2 fillna
fillna(): 填充缺失值。
import pandas as pd
from pandas import DataFrame
import numpy as np
# 创建一个示例DataFrame
data = {'A': [10, 20, 30, 40],
'B': [50, 60, 70, 80],
'C': [90, 100, 110, 120]}
df: DataFrame = pd.DataFrame(data)
# 60 和 80 的填充为 NaN
df[df.isin([60, 80])] = np.nan
# A B C
# 0 10 50.0 90
# 1 20 NaN 100
# 2 30 70.0 110
# 3 40 NaN 120
print(df)
df.fillna(-1, inplace=True)
# A B C
# 0 10 50.0 90
# 1 20 -1.0 100
# 2 30 70.0 110
# 3 40 -1.0 120
print(df)
2.4.3 drop_duplicates
drop_duplicates(): 删除重复的行。
- keep 可以指定如果重复是保留前面的,还是保留后面的。“first”, “last”
import pandas as pd
from pandas import DataFrame
# 创建一个示例DataFrame
data = {'A': [10, 10, 10, 40],
'B': [10, 60, 60, 80]}
df: DataFrame = pd.DataFrame(data)
# A 列有重复的就删除
# A B
# 0 10 10
# 3 40 80
print(df.drop_duplicates(subset='A'))
# A 和 B 列都重复就删除,默认保留第一个,后面重复的删除
# A B
# 0 10 10
# 1 10 60
# 3 40 80
print(df.drop_duplicates(subset=['A', 'B']))
# A 和 B 列都重复就删除,指定保留最后一个,前面的重复删除
# A B
# 0 10 10
# 2 10 60
# 3 40 80
print(df.drop_duplicates(subset=['A', 'B'], keep='last'))
2.4.4 replace
replace(): 替换指定的值。
参数 | 描述 |
---|---|
to_replace | 要替换的值,可以是单个值、字典、列表、正则表达式或其他可迭代对象 |
value | 替换后的值,可以是单个值、字典、列表或其他可迭代对象 |
inplace | 是否在原始DataFrame上进行就地替换,默认为False |
limit | 指定替换的次数,超过限制的替换将被忽略 |
regex | 是否使用正则表达式进行匹配替换,默认为False |
# 替换单个值:
df['column'].replace(10, 20)
# 将列中的所有值为10的替换为30,值为20的替换为40。
df['column'].replace([10, 20], [30, 40])
# 使用字典指定要替换的值和替换后的值。
df['column'].replace({10: 30, 20: 40})
# 使用正则表达式将列中值为"apple"的替换为"orange"。
df['column'].replace('^apple$', 'orange', regex=True)
2.4.5 astype
astype(): 转换列的数据类型。
# 将名为column的整数列转换为浮点数列。
df['column'] = df['column'].astype(float)
# 将名为column的浮点数列转换为整数列。
df['column'] = df['column'].astype(int)
# 将名为column的字符串列转换为日期时间列。
df['column'] = pd.to_datetime(df['column'])
# 将名为column的日期时间列转换为字符串列。
df['column'] = df['column'].astype(str)
2.4.6 sort_values
sort_values(): 根据指定的列进行排序。
# 按照名为column的列对DataFrame进行升序排序。
df.sort_values('column')
# 按照名为column的列对DataFrame进行降序排序。
df.sort_values('column', ascending=False)
# 按照DataFrame的索引进行倒排
df.sort_index(ascending=False)
2.5 数据统计和聚合
2.5.1 sum
sum(): 对列或行的值进行求和。
# 该示例将对 DataFrame 的每一列进行求和,并返回一个包含每列总和的 Series 对象。
total_sum = df.sum()
# 该示例将对名为 'column' 的列进行求和,并返回该列的总和。
column_sum = df['column'].sum()
# 该示例将对每一行进行求和,并返回一个包含每行总和的 Series 对象。
row_sum = df.sum(axis=1)
# 该示例将对名为 'column' 的列进行求和,忽略其中的缺失值(NaN)。
sum_without_na = df['column'].sum(skipna=True)
2.5.2 mean
mean(): 计算列或行的平均值。
# 该示例将对每一行计算平均值,并返回一个包含每行平均值的 Series 对象。
row_mean = df.mean(axis=1)
2.5.3 median
median(): 计算列或行的中位数。
对于一组数据,中位数(Median)是指将数据按照大小排序后,位于中间位置的数值。如果数据集有奇数个元素,那么中位数就是中间位置的数值;如果数据集有偶数个元素,那么中位数是中间两个数的平均值。
import pandas as pd
data = {'A': [10, 90, 60, 80],
'B': [20, 30, 40, 50]}
df = pd.DataFrame(data)
median_values = df['A'].median()
print(median_values)
# 输出:70.0
2.5.4 max
max(): 找到列或行的最大值。
series = pd.Series([1, 2, 3])
# 3
print(series.max())
2.5.5 min
min(): 找到列或行的最小值。
series = pd.Series([1, 2, 3])
# 1
print(series.min())
2.5.6 count
count(): 计算列或行的非空值数量。
series = pd.Series([1, 2, 3])
# 3
print(series.count())
2.5.7 groupby
groupby(): 按照指定的列进行分组。
import pandas as pd
data = {'产品': ['手机', '电视', '电脑', '手机', '电视'],
'销售员': ['张三', '李四', '王五', '张三', '李四'],
'销售额': [5000, 6000, 7000, 5500, 6500]}
df = pd.DataFrame(data)
# 产品 销售员 销售额
# 0 手机 张三 5000
# 1 电视 李四 6000
# 2 电脑 王五 7000
# 3 手机 张三 5500
# 4 电视 李四 6500
print(df)
grouped = df.groupby(['销售员', '产品'])
mean_sales = grouped['销售额'].sum()
# 销售员 产品
# 张三 手机 10500
# 李四 电视 12500
# 王五 电脑 7000
print(mean_sales)
2.6 数据合并和连接
2.6.1 concat
concat(): 将多个DataFrame按行或列进行连接。
import pandas as pd
data1 = {'A': [1, 2, 3],
'B': [4, 5, 6]}
data2 = {'C': [7, 8, 9],
'D': [10, 11, 12]}
df1 = pd.DataFrame(data1)
df2 = pd.DataFrame(data2)
## 竖向追加
# A B C D
# 0 1.0 4.0 NaN NaN
# 1 2.0 5.0 NaN NaN
# 2 3.0 6.0 NaN NaN
# 0 NaN NaN 7.0 10.0
# 1 NaN NaN 8.0 11.0
# 2 NaN NaN 9.0 12.0
print(pd.concat([df1, df2], axis=0))
# 横向追加
# A B C D
# 0 1 4 7 10
# 1 2 5 8 11
# 2 3 6 9 12
print(pd.concat([df1, df2], axis=1))
2.6.2 merge
merge(): 根据指定的列将多个DataFrame进行合并。
假设我们有两个数据集,一个包含客户信息,另一个包含订单信息。我们希望将这两个数据集根据客户ID进行合并,以便分析客户的订单行为。
- 主要用到merge方法
以下是merge()
方法中常用参数的补全,包括可选值和默认值:
参数 | 说明 | 可选值 | 默认值 |
---|---|---|---|
left | 左侧的DataFrame,要进行合并的左侧数据集。 | DataFrame | |
right | 右侧的DataFrame,要进行合并的右侧数据集。 | DataFrame | |
how | 合并方式,指定如何对齐和合并数据。 | ‘inner’, ‘outer’, ‘left’, ‘right’ | ‘inner’ |
on | 列名或列名列表,用于指定进行合并的列。 | 列名或列名列表 ,如果要关联的名称两笔都一样,可以直接用on | |
left_on | 左侧DataFrame中用于合并的列。 | 列名或列名列表,如果要关联的名称不一样,可以使用这个。支持列表参数 | |
right_on | 右侧DataFrame中用于合并的列。 | 列名或列名列表,如果要关联的名称不一样,可以使用这个。支持列表参数 | |
suffixes | 用于解决合并后列名冲突的后缀。 | 元组或列表 | (‘_x’, ‘_y’) |
如果你看不懂 how 的参数,可以参考下图。
import pandas as pd
# 客户信息数据集
customer_data = {
'客户ID': ['001', '002', '003'],
'姓名': ['张三', '李四', '王五'],
'年龄': [25, 30, 35]
}
df_customer = pd.DataFrame(customer_data)
# 订单信息数据集
order_data = {
'客户ID': ['001', '002', '003'],
'订单号': ['A001', 'A002', 'A003'],
'金额': [100, 200, 150]
}
df_order = pd.DataFrame(order_data)
# 数据合并,如果学过数据库,就会发现其实join
df_merged = pd.merge(df_customer, df_order, on='客户ID')
# 打印合并结果
# 客户ID 姓名 年龄 订单号 金额
# 0 001 张三 25 A001 100
# 1 002 李四 30 A002 200
# 2 003 王五 35 A003 150
print(df_merged)
2.7 数据可视化
pandas 中数据可视化,基于 matplotlib 图例较多,这里只列举常用的。更多的请参考官方文档。
官方学习地址
2.7.1 plot
plot(): 绘制DataFrame的图表,如折线图、柱状图等。
data = {'年份': [2015, 2016, 2017, 2018, 2019],
'销售额': [1000, 1500, 1200, 1800, 2000]}
df = pd.DataFrame(data)
# 绘制折线图
plt.plot(df['年份'], df['销售额'])
plt.xlabel('年份', fontproperties=font)
plt.ylabel('销售额', fontproperties=font)
plt.title('销售额趋势图', fontproperties=font)
plt.show()
# 柱状图
plt.bar(df['年份'], df['销售额'])
plt.xlabel('年份', fontproperties=font)
plt.ylabel('销售额', fontproperties=font)
plt.title('销售额趋势图', fontproperties=font)
plt.show()
2.7.2 hist
hist(): 绘制DataFrame的直方图。
import matplotlib.pyplot as plt
import pandas as pd
import numpy as np
plt.rcParams['font.sans-serif'] = ['Arial Unicode MS']
# 创建示例数据
data = np.random.randn(1000) # 生成随机数据
# 绘制直方图
plt.hist(data, bins=30, edgecolor='black')
# 设置坐标轴标签和标题
plt.xlabel('数值')
plt.ylabel('频数')
plt.title('直方图')
plt.show()
2.7.3 scatter
scatter(): 绘制DataFrame的散点图。
import matplotlib.pyplot as plt
import pandas as pd
plt.rcParams['font.sans-serif'] = ['Arial Unicode MS']
# 创建示例数据
data = {'身高': [160, 170, 165, 175, 180],
'体重': [50, 60, 55, 70, 75]}
# 创建 DataFrame
df = pd.DataFrame(data)
# 绘制散点图
df.plot(x='身高', y='体重', kind='scatter')
plt.show()
在本系列文章中,我们会从实战出发,深入探讨了Pandas数据分析库的众多功能和强大之处。掌握使用Pandas进行数据处理、清洗和分析的基本技巧。全系列课程均是免费。你的关注是我继续的动力。