Pandas

81 阅读10分钟

1.Series

1.1.Series 的构成

一个 Series 由两个主要部分组成:

  • Values (数据): 一组数据,存储为 NumPy 数组。
  • Index (索引): 与数据一一对应的标签。
Index      Values
'a'   ->     10
'b'   ->     20
'c'   ->     30
'd'   ->     40
Name: my_series, dtype: int64

创建一个Series

import pandas as pd
import numpy as np
s = pd.Series([10, 20, 30, np.nan], index=['a', 'b', 'c', 'd'], name='my_series')

1.2.Series属性

属性描述示例 s.attribute返回值
.values获取 Series 中的所有数据,返回一个 NumPy 数组。s.valuesarray([10., 20., 30., nan])
.index获取 Series 的索引对象。s.indexIndex(['a', 'b', 'c', 'd'], dtype='object')
.name获取或设置 Series 的名称。s.name'my_series'
.dtype获取 Series 中数据元素的类型。s.dtypedtype('float64')
.size返回 Series 中元素的数量 (包括 NaN)。s.size4
.shape返回一个表示 Series 维度的元组。s.shape(4,)
.ndim返回 Series 的维度数量 (永远是 1)。s.ndim1
.hasnans检查 Series 是否包含任何 NaN (缺失值)。s.hasnansTrue
.empty检查 Series 是否为空。s.emptyFalse

1.3.Series 的常用方法

1.3.1.查看与信息

方法描述示例
.head(n)查看前 n 行数据 (默认 n=5)。s.head(2)
.tail(n)查看后 n 行数据 (默认 n=5)。s.tail(2)
.describe()生成描述性统计信息 (计数、均值、标准差、最小值、分位数、最大值)。s.describe()
.value_counts()统计每个唯一值出现的次数,并按频率降序排列。对分类数据极其有用。s.value_counts()
.unique()返回一个包含 Series 中所有唯一值的数组。s.unique()
.nunique()返回 Series 中唯一值的数量。s.nunique()

1.3.2.数据计算

方法描述示例
.sum()计算所有值的总和。s.sum()
.mean()计算所有值的平均值。s.mean()
.median()计算所有值的中位数。s.median()
.std()计算标准差。s.std()
.min()/.max()返回最小值/最大值。s.min()
.idxmin()/.idxmax()返回最小值/最大值对应的索引标签s.idxmin()

1.3.3.数据修改

方法描述示例
.apply(func)将一个函数 func 应用于 Series 的每个元素。非常灵活。s.apply(lambda x: x**2)
.map(dict or Series)根据字典或另一个 Series 的映射关系来替换值。s.map({10: 'A', 20: 'B'})
.astype(dtype)转换 Series 的数据类型。s.astype(str)
.fillna(value)填充 NaN 缺失值。s.fillna(0)
.dropna()移除所有包含 NaN 的元素。s.dropna()
.replace(to_replace, value)替换指定的值。s.replace(10, 100)
.sort_values()按值对 Series 进行排序。s.sort_values(ascending=False)
.sort_index()按索引对 Series 进行排序。s.sort_index()

2.DataFrame

2.1.DataFrame的构成

一个 DataFrame 由三个主要部分协同工作:

  1. data (数据): 一个二维的数据块,可以容纳多种数据类型。
  2. index (行索引): 每行的唯一标识符,类似于数据库中的主键。
  3. columns (列索引): 每列的名称。
           <---------- columns ---------->
           'name'    'age'    'city'
         +---------+--------+------------+
's01' -> | 'Anna'  |   28   | 'New York' |  <--
's02' -> | 'Bob'   |   34   | 'Los Angeles'|  |
's03' -> | 'Charles'|   29  | 'Chicago'  |  | index
's04' -> | 'David' |   42   | 'New York' |  |
         +---------+--------+------------+
                ^
                |
           data (values)

创建DataFrame

  1. 从字典创建 (最常用)
import pandas as pd
import numpy as np

# 字典的值是列表,长度必须一致
data_dict = {
    'name': ['Anna', 'Bob', 'Charles', 'David'],
    'age': [28, 34, 29, 42],
    'score': [85.5, 90.0, 78.5, 92.0]
}
df_from_dict = pd.DataFrame(data_dict, index=['s01', 's02', 's03', 's04'])
  1. 从列表的列表创建
data_list = [    ['Anna', 28, 85.5],
    ['Bob', 34, 90.0],
    ['Charles', 29, 78.5]
]
df_from_list = pd.DataFrame(data_list, columns=['name', 'age', 'score'])
  1. 从NumPy数组创建
data_array = np.array([    [1, 2, 3],
    [4, 5, 6]
])
df_from_array = pd.DataFrame(data_array, columns=['A', 'B', 'C'])

2.2.DataFrame的属性

属性描述示例 df.attribute返回值
.index获取 DataFrame 的行索引。df.indexIndex(['s01', 's02', 's03', 's04'], dtype='object')
.columns获取 DataFrame 的列索引(列名)。df.columnsIndex(['name', 'age', 'score'], dtype='object')
.values获取 DataFrame 的所有数据,返回一个 NumPy 数组。df.valuesarray([['Anna', 28, 85.5], ...])
.dtypes返回一个包含每列数据类型的 Series。df.dtypesname object, age int64, score float64
.shape返回一个表示 DataFrame 维度的元组 (行数, 列数)。df.shape(4, 3)
.size返回 DataFrame 中元素的总数量 (行数 * 列数)。df.size12
.ndim返回 DataFrame 的维度数量 (永远是 2)。df.ndim2
.empty检查 DataFrame 是否为空。df.emptyFalse
.T转置 DataFrame,即行和列互换。df.T一个新的转置后的 DataFrame

2.3.DataFrame的方法

2.3.1.查看与信息

方法描述
.head(n) / .tail(n)查看前/后 n 行数据 (默认 n=5)。
.info()提供 DataFrame 的简洁摘要,包括索引、列、非空值数量和内存使用情况。非常重要!
.describe()生成数值列的描述性统计信息。
.sample(n)随机抽取 n 行样本。

2.3.2.数据选择与筛选

类别方法 / 语法主要用途返回值类型
基础列选择df['col']选择单个列。Series
df[['col1', 'col2']]选择多个列。DataFrame
标签选择 (.loc)df.loc['row_label']按标签选择单个行。Series
df.loc[['label1', 'label2']]按标签选择多个行(列表)。DataFrame
df.loc['start':'end']按标签选择连续多行(切片)。DataFrame
df.loc['row', 'col']按标签选择单个值标量 (Scalar)
df.loc[rows, cols]按标签选择行和列的子集DataFrame
df.loc[:, 'col']按标签选择所有行的特定列。Series
位置选择 (.iloc)df.iloc[pos]按整数位置选择单个行。Series
df.iloc[[pos1, pos2]]按整数位置选择多个行(列表)。DataFrame
df.iloc[start:end]按整数位置选择连续多行(切片)。DataFrame
df.iloc[row_pos, col_pos]按整数位置选择单个值标量 (Scalar)
df.iloc[rows, cols]按整数位置选择行和列的子集DataFrame
条件筛选df[condition]基于布尔条件筛选行。DataFrame
df[cond1 & cond2]基于多个与条件筛选行。DataFrame
df[cond1 | cond2]基于多个或条件筛选行。DataFrame
df.query('expr')使用字符串表达式筛选行。DataFrame
df[df['col'].isin(list)]筛选列值在给定列表中的行。DataFrame
属性筛选df.select_dtypes(...)选择特定数据类型的列。DataFrame
df[df['col'].str.method()]基于字符串方法筛选行。ataFrame

2.3.3.数据修改与处理

方法描述
.drop()删除指定的行或列。需要指定 axis=0 (行) 或 axis=1 (列)。
.rename()重命名行索引或列名。
.assign()创建一个或多个新列,并返回一个新的 DataFrame。适合链式操作。
.astype()转换一个或多个列的数据类型。
.sort_values()按一列或多列的值进行排序。
.sort_index()按行或列的索引进行排序。
.reset_index()将行索引重置为默认的整数索引,并将原索引添加为新的一列。
.set_index()将现有的一列或多列设置为新的行索引。

2.3.4.数据清洗

方法描述
.isnull() / .isna()检测缺失值 (NaN),返回一个布尔型的 DataFrame。
.notnull() / .notna()检测非缺失值。
.fillna()填充缺失值。
.dropna()删除包含缺失值的行或列。
.duplicated()检测重复行,返回一个布尔型的 Series。
.drop_duplicates()删除重复行。

2.3.5.数据的聚合与分组

方法描述
.groupby()根据一列或多列的值对数据进行分组,是进行聚合分析的核心。
.agg() / .aggregate()在分组后应用一个或多个聚合函数 (如 sum, mean, count)。
.pivot_table()创建一个类似电子表格数据透视表的功能。
.merge()根据一个或多个键将两个 DataFrame 进行数据库风格的合并。
.join()根据索引将两个 DataFrame 进行合并。
.concat()沿着一个轴(行或列)将多个 DataFrame 堆叠在一起。

2.4.数据选择和筛选方式

2.4.1.基础列选择 [...]

  • 选择单列(返回Series)
# 用法: 传入一个列名的字符串 
# 返回值: pandas.Series 
df['name']
  • 选择多列(返回DataFrame)
# 用法: 传入一个包含列名的列表 
# 返回值: pandas.DataFrame 
df[['name', 'age']]

2.4.2.基于标签的精准选择:.loc

.loc 是 Pandas 官方推荐的、基于 行索引标签 和 列名 的选择器。它的语法是 df.loc[row_labels, column_labels],清晰且无歧义。

  • 选择行
# 选择单行
# 返回值: pandas.Series 
df.loc['s02']

# 选择多行
# 返回值: pandas.DataFrame
df.loc[['s01', 's03']]

# 使用切片选择行 (注意:.loc 的切片包含结束标签)
# 返回值: pandas.DataFrame
df.loc['s02':'s04']
  • 选择列
# 只选择列(单列)
# 返回值: pandas.Series
df.loc[:, 'age']

# 只选择列(多列)
# 返回值: pandas.DataFrame
df.loc[:, ['age', 'city']]

# 同时选择行和列
# 返回值: pandas.DataFrame
df.loc[['s01','s04'], ['name','score']]

# 结合条件选择
# 返回值: pandas.DataFrame
df.loc[df['age'] > 40, ['name', 'city']]

2.4.3.基于整数位置的快速选择:.iloc

与 .loc 类似,但完全基于整数位置 (从 0 开始)。语法是 df.iloc[行位置, 列位置]。

  • 选择行
# 选择单行
# 返回值: pandas.Series
df.iloc[1] (第二行)

# 选择多行 (列表)
# 返回值: pandas.DataFrame
df.iloc[[0, 2, 4]]

# 选择多行 (切片)
# 返回值: pandas.DataFrame
df.iloc[1:4] (第 2, 3, 4 行)
  • 选择列
# 选择单个值
# 返回值: 标量 (e.g., str, int, float)
df.iloc[2, 0] (第 3 行, 第 1 列)

# 同时选择行和列
# 返回值: pandas.DataFrame
df.iloc[0:3, [0, 2]]

2.4.4.布尔索引

最核心、最灵活的筛选方式。先创建一个布尔(True/False)序列,然后用它来筛选 DataFrame。

# 单一条件
# pandas.DataFrame
df[df['age'] > 30]

# 多重条件
# pandas.DataFrame
df[(df['age'] > 30) & (df['city'] == 'New York')]

2.4.5..isin() 方法

筛选出某个列的值属于一个特定集合的行。

# 成员资格检查
# pandas.DataFrame
df[df['city'].isin(['Chicago', 'New York'])]

2.4.6..query() 方法

使用字符串表达式进行筛选,代码可读性高。

# 字符串表达式
# pandas.DataFrame
df.query('age > 30 and active == True')

# 使用外部变量
# pandas.DataFrame
min_score = 80; 
df.query('score > @min_score')

2.4.7.按类型选择 .select_dtypes()

# 包含特定类型
# pandas.DataFrame
df.select_dtypes(include='number')
df.select_dtypes(include=['bool','number'])

# 排除特定类型
# pandas.DataFrame
df.select_dtypes(exclude=['object', 'bool'])

3.Index

3.1. Index 的作用与构成

一个 Index 对象主要由以下部分构成:

  • Labels (标签): 一组标签,用于标识数据。它们被存储在一个类似数组的结构中。
  • dtype (数据类型): 标签的数据类型,例如 object (字符串)、int64 (整数) 或 datetime64[ns] (日期时间)。
  • name (名称): Index 对象本身的可选名称。
TypeName([label1, label2, ...], dtype='...', name='...')

3.2. Index 的核心特性

特性描述
不可变性 (Immutable)Index 对象一旦创建,其内部的元素就不能被修改。这确保了数据在操作中的稳定性和安全性。任何看似修改的操作(如 drop)都会返回一个新的 Index 对象。
同质性 (Homogeneous)通常情况下,一个 Index 对象中的所有标签都具有相同的数据类型,这有助于性能优化。
性能优化Index 内部通常使用哈希表等结构,使得基于标签的查找、数据对齐和集合运算非常高效,远快于普通的 Python 列表。

3.3. Index 的属性

属性描述示例 idx.attribute返回值
.values获取 Index 中的所有标签,返回一个 NumPy 数组。idx_col.valuesarray(['city', 'temp', 'humidity'], dtype=object)
.name获取或设置 Index 的名称。idx_row.name'record_id'
.dtype获取 Index 中标签的数据类型。idx_col.dtypedtype('O')
.size返回 Index 中标签的数量。idx_col.size3
.shape返回一个表示 Index 维度的元组 (永远是 1 维)。idx_col.shape(3,)
.ndim返回 Index 的维度数量 (永远是 1)。idx_col.ndim1
.hasnans检查 Index 是否包含任何 NaN (缺失值)。idx_col.hasnansFalse
.is_unique检查 Index 中的所有标签是否都是唯一的。idx_col.is_uniqueTrue
.empty检查 Index 是否为空。idx_col.emptyFalse

3.4. Index 的方法

3.4.1. 集合运算

方法描述示例
.intersection(other)计算两个 Index 的交集。idx1.intersection(idx2) (返回 Index(['c', 'd'], dtype='object'))
.union(other)计算两个 Index 的并集。idx1.union(idx2) (返回 Index(['a', 'b', 'c', 'd', 'e', 'f'], dtype='object'))
.difference(other)计算差集 (在 idx1 中但不在 idx2 中)。idx1.difference(idx2) (返回 Index(['a', 'b'], dtype='object'))
.symmetric_difference(other)计算对称差集 (只存在于其中一个 Index 中的元素)。idx1.symmetric_difference(idx2) (返回 Index(['a', 'b', 'e', 'f'], dtype='object'))

3.4.2. 信息查看与转换

方法描述示例
.tolist()将 Index 对象转换为一个标准的 Python 列表 list。idx_col.tolist() (返回 ['city', 'temp', 'humidity'])
.to_series()将 Index 对象转换为一个 Series,其值和索引都是 Index 的标签。idx1.to_series()
.get_loc(label)获取指定标签的整数位置。如果标签不唯一,会报错。idx_col.get_loc('temp') (返回 1)
.isin(values)检查 Index 中的每个标签是否存在于 values 集合中,返回一个布尔数组。idx1.isin(['b', 'e']) (返回 array([False, True, False, False]))
.unique()返回一个包含 Index 中所有唯一值的新 Index。pd.Index(['a','b','a']).unique()

3.4.3. 修改与操作 (返回新对象)

重要: 由于 Index 是不可变的,这些方法都不会修改原始 Index,而是返回一个新的 Index 对象。

方法描述示例
.drop(labels)移除指定的标签,返回一个新的 Index。new_idx = idx1.drop('c')
.insert(loc, item)在指定整数位置 loc 插入一个新标签 item,返回新 Index。new_idx = idx1.insert(1, 'x') (返回 Index(['a', 'x', 'b', 'c', 'd']))
.append(other)将另一个 Index 或类数组对象连接到当前 Index 的末尾,返回新 Index。new_idx = idx1.append(idx2)
.astype(dtype)转换 Index 的数据类型,返回新 Index。pd.Index([1, 2, 3]).astype(str)
.rename(name)为 Index 设置新的名称,返回新 Index。new_idx = idx_col.rename('features')
.sort_values()对 Index 的标签进行排序,返回新 Index。pd.Index(['c','a','b']).sort_values()