第三篇:深入了解Pandas数据结构:Series与DataFrame

本篇文章深入介绍了Pandas的Series和DataFrame数据结构,包括创建、查看、选择、清洗及统计分析的方法,如head(),tail(),info(),describe(),drop(),fillna(),groupby()等,旨在帮助读者熟练运用Pandas进行数据操作。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

在这里插入图片描述

作者: 西魏陶渊明
博客: 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进行数据处理、清洗和分析的基本技巧。全系列课程均是免费。你的关注是我继续的动力。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

西魏陶渊明

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值