Pandas 简介

3.1.1  Pandas 是什么?

Pandas 是 Python 数据分析工具链中最核心的库,充当数据读取、清洗、分析、统计、输出的高效工具。

Pandas 是一个开源的数据分析和数据处理库,它是基于 Python 编程语言的。

Pandas 提供了易于使用的数据结构和数据分析工具,特别适用于处理结构化数据,如表格型数据(类似于Excel表格)。

Pandas 是数据科学和分析领域中常用的工具之一,它使得用户能够轻松地从各种数据源中导入数据,并对数据进行高效的操作和分析。

Pandas是基于NumPy构建的专门为处理表格和混杂数据设计的Python库,其核心设计理念包括:

  • 标签化数据结构:提供带标签的轴(行索引和列名)
  • 灵活处理缺失数据:内置NaN处理机制
  • 智能数据对齐:自动按标签对齐数据
  • 强大IO工具:支持从CSV、Excel、SQL等20+数据源读写
  • 时间序列处理:原生支持日期时间处理和频率转换

名称由来

pandas这个名字源于panel data(面板数据,这是多维结构化数据集在计量经济学中的术语)以及Python data analysis(Python数据分析)。

pandas兼具numpy高性能的数组计算功能以及电子表格和关系型数据库(如SQL)灵活的数据处理功能。它提供了复杂精细的索引功能,能更加便捷地完成重塑、切片和切块、聚合以及选取数据子集等操作。

pandas功能:

  • 有标签轴的数据结构

在数据结构中,每个轴都被赋予了特定的标签,这些标签用于标识和引用轴上的数据元素,使得数据的组织、访问和操作更加直观和方便

应用场景

工具

功能特色

适用场景

Excel

图形界面,简单上手

人工分析、小规模数据

SQL

高效读写,最终数据源

数据库查询和联表

Python + Pandas

算法和分析部署核心

数据清洗,统计分析,可视化等

  1. Excel对比
  • 优势:
  • 处理百万级数据不卡顿(Excel约100万行限制)
  • 可复用的分析流程(脚本 vs 手工操作)
  • 支持复杂数据转换(如:分组聚合、时间重采样)
  • 局限:
  • 可视化交互性较弱
  • 学习曲线较陡峭
  1. 与数据库对比
  • 优势:
  • 无需SQL知识即可分析
  • 适合探索性分析(即时反馈)
  • 丰富的数据清洗函数
  • 局限:
  • 数据量受内存限制
  • 不适合高并发访问
  1. 与纯Python代码对比
  • 优势:
  • 向量化运算比for循环快10-100倍
  • 内置统计分析方法(如:相关系数计算)
  • 丰富的数据透视功能
  • 局限:
  • 需要额外学习Pandas API

行业洞见:根据2023年Kaggle调查,Pandas是数据科学家使用率最高的工具(占比93%),远超第二名Excel(占比32%)

3.1.2 了解 Pandas 核心数据结构:Series  DataFrame

Pandas 基于 Numpy,并提供了 2 大核心数据结构:

  • Series:一维带有标签的数组
  • DataFrame:二维表格结构,可看作多个 Series 的组合

用得最多的pandas对象是Series,一个一维的标签化数组对象,另一个是DataFrame,它是一个面向列的二维表结构。

特性

Series

DataFrame

维度

一维

二维

索引

单索引

行索引+列名

数据存储

同质化数据类型

各列可不同数据类型

类比

Excel单列

整张Excel工作表

创建方式

pd.Series([1,2,3])

pd.DataFrame({'col':[1,2,3]})

Pandas 与 Numpy 的关系与区别

就像学习数学要先掌握算术才能学代数一样,NumPy就是数据分析的"算术基础"。虽然可以直接用计算器(Pandas),但理解底层原理才能走得更远。

3.2 核心数据结构:Series

3.2.1 创建与访问

什么是Series

类似于 NumPy 一维数组,但增加了 "标签",可以理解为「一维标签化数组」

Series 是 Pandas 中的一个核心数据结构,类似于一个一维的数组,具有数据和索引。

Series 可以存储任何数据类型(整数、浮点数、字符串等),并通过标签(索引)来访问元素。Series 的数据结构是非常有用的,因为它可以处理各种数据类型,同时保持了高效的数据操作能力,比如可以通过标签来快速访问和操作数据。

Series 特点:

  • 一维数组:Series 中的每个元素都有一个对应的索引值。
  • 索引: 每个数据元素都可以通过标签(索引)来访问,默认情况下索引是从 0 开始的整数,但你也可以自定义索引。
  • 数据类型: Series 可以容纳不同数据类型的元素,包括整数、浮点数、字符串、Python 对象等。
  • 大小不变性:Series 的大小在创建后是不变的,但可以通过某些操作(如 append 或 delete)来改变。
  • 操作:Series 支持各种操作,如数学运算、统计分析、字符串处理等。
  • 缺失数据:Series 可以包含缺失数据,Pandas 使用NaN(Not a Number)来表示缺失或无值。
  • 自动对齐:当对多个 Series 进行运算时,Pandas 会自动根据索引对齐数据,这使得数据处理更加高效。

我们可以使用 Pandas 库来创建一个 Series 对象,并且可以为其指定索引(Index)、名称(Name)以及值(Values):

Python
import pandas as pd
s = pd.Series([10, 20, 30], index=["a", "b", "c"])

创建Series

直接通过列表创建Series

Python
import pandas as pd
s = pd.Series([4, 7, -5, 3])
print(s)
# 0    4
# 1    7
# 2   -5
# 3    3
# dtype: int64

Series的字符串表现形式为:索引在左边,值在右边。由于我们没有为数据指定索引,于是会自动创建一个0N-1N为数据的长度)的整数型索引。

  • 通过列表创建Series时指定索引
Python
s = pd.Series([4, 7, -5, 3], index=["a", "b", "c", "d"])
print(s)
# a    4
# b    7
# c   -5
# d    3
# dtype: int64

  • 通过列表创建Series时指定索引和名称
Python
s = pd.Series([4, 7, -5, 3], index=["a", "b", "c", "d"],name="hello_python")
print(s)
# a    4
# b    7
# c   -5
# d    3
# Name: hello_python, dtype: int6

名称的作用,与变量名的区别

在 Pandas 的 Series 中,name 参数用于给整个 Series 对象赋予一个名称。这个名称有以下几个用途:

1. 标识作用

  • name 可以作为 Series 的标识,类似于给数据列取一个名字。
  • 当你打印 Series 时,name 会显示在输出的最下方(如你的例子所示)。

2. DataFrame 列名

  • 如果你将一个 Series 转换成 DataFrame 或与其他 DataFrame 合并,name 会自动成为列名。
  • 例如:
Python
df = s.to_frame()  # 转换为 DataFrame,列名就是 "hello_python"
print(df)

输出:

Plain Text
   hello_python
a             4
b             7
c            -5
d             3

3. 对齐操作

  • 在 Pandas 运算(如 concatmerge 等)时,name 可以帮助对齐数据。

4. 导出数据

  • 当你将 Series 导出为 CSV 或其他格式时,name 会成为列名。

name 的主要作用是 给 Series 一个标识,方便后续数据处理、合并或导出。如果只是单独使用 Series,name 可能看起来作用不大,但在更复杂的数据操作中(如 DataFrame 整合),它会很有用。

  • 直接通过字典创建Series
Python
dic = {"a": 4, "b": 7, "c": -5, "d": 3}
s = pd.Series(dic)
print(s)
# a    4
# b    7
# c   -5
# d    3
# dtype: int64
s1 = pd.Series(dic,index=["a","c"],name="aacc")
print(s1)
# a    4
# c   -5
# Name: aacc, dtype: int64

访问Series数据

以下是 Pandas 中访问 Series 数据的主要方法汇总表格:

方法分类

语法示例

描述

返回值

是否支持切片/布尔索引

位置索引

s.iloc[0]

通过整数位置访问(从0开始)

标量值

s.iloc[1:3]

位置切片(左闭右开)

Series

标签索引

s.loc['a']

通过索引标签访问

标量值

s.loc[['a','b']]

通过标签列表访问

Series

直接索引

s[0]

类似iloc(当索引非整数时可能混淆)

标量值/Series

s['a']

类似loc(优先标签索引)

布尔索引

s[s > 3]

通过布尔条件筛选

Series

s[~(s > 3)]

取反条件

函数访问

s.at['a']

快速访问单个标签(类似loc但效率更高)

标量值

s.iat[0]

快速访问单个位置(类似iloc但效率更高)

头部/尾部

s.head(3)

访问前N行(默认5)

Series

s.tail(2)

访问后N行(默认5)

取唯一值

s.unique()

返回唯一值数组

ndarray

值计数

s.value_counts()

统计各值出现次数

Series

  1. 优先使用**loc****/****iloc**:直接索引[]的行为可能因索引类型不同而变化,明确场景时建议显式使用loc(标签)或iloc(位置)。
  1. 切片差异
  • loc切片为闭区间(包含两端)
  • iloc切片为左闭右开(与Python列表一致)
  1. 布尔索引:常用于条件过滤,如s[s > 3 & s < 10]
Python
s = pd.Series([10, 20, 30, 40], index=['a', 'b', 'c', 'd'])
# 位置索引
print(s.iloc[0])  # 10
# 标签访问
s["a"]    
# 标签索引
print(s.loc['b'])  # 20
# 布尔索引
print(s[s > 25])  # c:30, d:40
# 花式索引
print(s[['a', 'c']])  # a:10, c:30

#使用布尔索引从Series中筛选满足某些条件的值
bools = s > s.mean()  # 将大于平均值的元素标记为 True
print(bools)
# a    False
# b     True
# c     True
# d    False
# dtype: bool
print(s[bools])
# b    3.5
# c    6.8
# dtype: float64
# 使用where过滤
print(s.where(s > 20, -1))  # 小于等于20的值替换为-1

Series的常用属性

属性

说明

index

Series的索引对象

values

Series的值

dtypedtypes

Series的元素类型

shape

Series的形状

ndim

Series的维度

size

Series的元素个数

name

Series的名称

loc[]

显式索引,按标签索引或切片

iloc[]

隐式索引,按位置索引或切片

at[]

使用标签访问单个元素

iat[]

使用位置访问单个元素

Python
import pandas as pd
arrs = pd.Series([11,22,33,44,55],name="atguigu",index=["a","b","c","d","e"])
# print(arrs)
# index Series的索引对象
print(arrs.index)
for i in arrs.index:
    print(i)
print(arrs.values) # values    Series的值
print(arrs.ndim)  # ndim  Series的维度
print(arrs.shape)  # shape Series的形状
print(arrs.size) # size  Series的元素个数
# dtype或dtypes  Series的元素类型
print(arrs.dtype)
print(arrs.dtypes)
# name  Series的名称
print(arrs.name)
# loc[] 显式索引,按标签索引或切片
print(arrs.loc["c"])
print(arrs.loc["c":"d"])
# iloc[]    隐式索引,按位置索引或切片
print(arrs.iloc[0])
print(arrs.iloc[0:3])
# at[]  使用标签访问单个元素
print(arrs.at["a"])
# iat[] 使用位置访问单个元素
print(arrs.iat[3])

3.2.2 Series的运算

Plain Text
s1 = pd.Series([1, 2, 3, 4])
s2 = pd.Series([10, 20, 30, 40])
# 基本运算
print(s1 + s2)  # 对应位置相加
print(s1 * 2)   # 标量乘法

3.2.3 常用方法与统计

用途分类

方法

说明

示例代码

数据预览

head()

查看前 n 行数据,默认 5 行

s.head(3)

数据预览

tail()

查看后 n 行数据,默认 5 行

s.tail(2)

条件判断

isin()

判断元素是否包含在参数集合中

s.isin([1, 2])

缺失值处理

isna()

判断是否为缺失值(如 NaN 或 None)

s.isna()

聚合统计

sum()

求和,自动忽略缺失值

s.sum()

聚合统计

mean()

平均值

s.mean()

聚合统计

min()

最小值

s.min()

聚合统计

max()

最大值

s.max()

聚合统计

var()

方差

s.var()

聚合统计

std()

标准差

s.std()

聚合统计

median()

中位数

s.median()

聚合统计

mode()

众数(可返回多个)

s.mode()

聚合统计

quantile(q)

分位数,q 取 0~1 之间

s.quantile(0.25)

聚合统计

describe()

常见统计信息(count、mean、std、min、25%、50%、75%、max)

s.describe()

频率统计

value_counts()

每个唯一值的出现次数

s.value_counts()

频率统计

count()

非缺失值数量

s.count()

频率统计

nunique()

唯一值个数(去重)

s.nunique()

唯一处理

unique()

获取去重后的值数组

s.unique()

唯一处理

drop_duplicates()

去除重复项

s.drop_duplicates()

抽样分析

sample()

随机抽样

s.sample(2)

排序操作

sort_index()

按索引排序

s.sort_index()

排序操作

sort_values()

按值排序

s.sort_values()

替换值

replace()

替换值

s.replace({1: 100})

转换结构

to_frame()

将 Series 转为 DataFrame

s.to_frame()

比较判断

equals()

判断两个 Series 是否完全相等

s1.equals(s2)

信息提取

keys()

返回 Series 的索引对象

s.keys()

统计关系

corr()

计算相关系数(默认皮尔逊)

s1.corr(s2)

统计关系

cov()

协方差

s1.cov(s2)

可视化

hist()

绘制直方图(需安装 matplotlib)

s.hist()

遍历操作

items()

返回索引和值的迭代器

for i, v in s.items(): print(i, v)

Python
import pandas as pd
import numpy as np
arrs = pd.Series([11,22,np.nan,None,44,22],index=['a','b','c','d','e','f'])
# head()    查看前n行数据,默认5行
print(arrs.head())
# tail()    查看后n行数据,默认5行
print(arrs.tail(3))
# describe()    常见统计信息
print(arrs.describe())
# count()   非缺失值元素的个数
print(arrs.count())
# keys()    返回Series的索引对象
print(arrs.index)
print(arrs.keys())
# isin()    判断数组中的每一个元素是否包含在参数集合中
print(arrs.isin([11]))
# isna()    元素是否为缺失值
print(arrs.isna())

#统计
# sum() 求和,会忽略 Series 中的缺失值
print(arrs.sum())
# mean()    平均值
print(arrs.mean())
# min() 最小值
print(arrs.min())
# max() 最大值
print(arrs.max())
# var() 方差 每个元素与平均值的差 的平方 的和
print(arrs.var())
# std() 标准差 方差的平方根
print(arrs.std())
# print(arrs.var())
# median()  中位数
# 若数据集的元素个数为奇数,中位数就是排序后位于中间位置的数值。
# 若数据集的元素个数为偶数,中位数则是排序后中间两个数的平均值。
# 去除缺失值之后,arrs 就变成了 [11, 22, 44, 22]。
# 对 [11, 22, 44, 22] 进行排序,得到 [11, 22, 22, 44]
print(arrs.median())
# mode()    众数
print(arrs.mode())
# quantile()    指定位置的分位数,如quantile(0.5)
# 分位数:分位数是把一组数据按照从小到大的顺序排列后,分割成若干等份的数值点。
# 0.25 分位数就是将数据从小到大排序后,位于 25% 位置处的数值。
# 插值方法:当计算分位数时,若位置不是整数,就需要借助插值方法来确定分位数值。# "midpoint" 插值方法是指当分位数位置处于两个数据点之间时,取这两个数据点的
# 平均值作为分位数值。
# 对于有 n个数据点的有序数据集,q分位数的位置 i可以通过公式 i=(n−1)q来计
# 算。这里 n=4,q=0.25,则 i=(4−1)×0.25=0.75。这意味着 0.25 分位数处于第一个# 数据点(值为 11)和第二个数据点(值为 22)之间。使用 "midpoint" 插值方法,
# 分位数值就是这两个数据点的平均值,即 (11+22)÷2=16.5
print(arrs.quantile(0.25, interpolation="midpoint"))


print(len(arrs))
# drop_duplicates() 去重  这里可以看出,底层None也作为NaN处理
print(arrs.drop_duplicates())
# unique()  去重后的数组
print(arrs.unique())
# nunique() 去重后非缺失值元素元素个数
print(arrs.nunique())
# sample()  随机采样
print(arrs.sample())
# value_counts()    每个元素的个数
print(arrs.value_counts())

# sort_index()  按索引排序
print(arrs.sort_index())

# sort_values() 按值排序
print(arrs.sort_values())
# replace() 用指定值代替原有值
print(arrs.replace(22,"haha"))

# to_frame()    将Series转换为DataFrame
print(arrs.to_frame())

# equals()  判断两个Series是否相同
arr1 = pd.Series([1,2,3])
arr2 = pd.Series([1,2,3])
print(arr1.equals(arr2))

# corr()    计算与另一个Series的相关系数
# arr1.corr(arr2):由于 arr1 和 arr2 的值完全相同,它们之间是完全正相关的,
#因此相关系数为 1。
# arr1.corr(arr3):arr1 的值是递增的,而 arr3 的值是递减的,它们之间是完全
# 负相关的,所以相关系数为 -1。
# arr1.corr(arr4):arr1 和 arr4 的值都是递增的,且变化趋势一致,它们之间是
# 完全正相关的,相关系数为 1。
# arr5.corr(arr6):arr5 和 arr6 的值之间没有明显的线性关系,它们的相关系数
# 为 0。
arr3 = pd.Series([3,2,1])
arr4 = pd.Series([6,7,8])
arr5 = pd.Series([1, -1, 1, -1])
arr6 = pd.Series([1, 1, -1, -1])
print(arr1.corr(arr2))
print(arr1.corr(arr3))
print(arr1.corr(arr4))
print(arr5.corr(arr6))

# cov() 计算与另一个Series的协方差
# 协方差用于衡量两个变量的总体误差,其值的正负表示两个变量的变化方向关系:
# 正值表示同向变化,负值表示反向变化。
print(arr1.cov(arr3))

Logo

DAMO开发者矩阵,由阿里巴巴达摩院和中国互联网协会联合发起,致力于探讨最前沿的技术趋势与应用成果,搭建高质量的交流与分享平台,推动技术创新与产业应用链接,围绕“人工智能与新型计算”构建开放共享的开发者生态。

更多推荐