数据结构

Series

一维带标签数组,能够保存任何数据类型

1
2
3
4
5
6
7
8
9
import pandas as pd
import numpy as np

# 创建 Series
s = pd.Series([1, 3, 5, np.nan, 6, 8])
s = pd.Series([1, 2, 3, 4], index=['a', 'b', 'c', 'd'])

# 从字典创建
s_dict = pd.Series({'a': 1, 'b': 2, 'c': 3})

DataFrame

二维标签数据结构,类似于电子表格或 SQL 表

1
2
3
4
5
6
7
8
9
10
11
12
13
# 创建 DataFrame
df = pd.DataFrame({
'A': 1.0,
'B': pd.Timestamp('20230101'),
'C': pd.Series(1, index=list(range(4)), dtype='float32'),
'D': np.array([3] * 4, dtype='int32'),
'E': pd.Categorical(["test", "train", "test", "train"]),
'F': 'foo'
})

# 从列表的列表创建
data = [['Alice', 25], ['Bob', 30], ['Charlie', 35]]
df = pd.DataFrame(data, columns=['Name', 'Age'])

数据导入与导出

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
# 读取 CSV 文件
df = pd.read_csv('file.csv')

# 读取 Excel 文件
df = pd.read_excel('file.xlsx', sheet_name='Sheet1')

# 读取 JSON 文件
df = pd.read_json('file.json')

# 保存到 CSV
df.to_csv('output.csv', index=False)

# 保存到 Excel
df.to_excel('output.xlsx', sheet_name='Sheet1', index=False)

# 保存到 JSON
df.to_json('output.json')

数据查看与选择

查看数据

1
2
3
4
5
6
7
8
9
df.head()        # 前5行
df.tail() # 后5行
df.sample(5) # 随机5行
df.info() # 数据信息
df.describe() # 统计摘要
df.shape # 形状 (行数, 列数)
df.columns # 列名
df.index # 索引
df.dtypes # 每列数据类型

选择数据

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
# 选择列
df['A'] # 选择单列,返回 Series
df[['A', 'B']] # 选择多列,返回 DataFrame

# 使用 loc 按标签选择
df.loc[0] # 选择第一行
df.loc[0:2] # 选择第一到第三行
df.loc[0:2, 'A':'B'] # 选择行和列的范围

# 使用 iloc 按位置选择
df.iloc[0] # 第一行
df.iloc[0:3] # 第一到第三行
df.iloc[0:3, 0:2] # 行和列的位置范围

# 布尔索引
df[df['A'] > 0.5] # A列大于0.5的行
df[(df['A'] > 0.5) & (df['B'] < 1)] # 多个条件
df[df['E'].isin(['test'])] # E列值为'test'的行

数据清洗

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
# 处理缺失值
df.dropna() # 删除含有缺失值的行
df.dropna(axis=1) # 删除含有缺失值的列
df.fillna(value) # 填充缺失值
df.isna() # 判断缺失值
df.notna() # 判断非缺失值

# 处理重复值
df.duplicated() # 检查重复行
df.drop_duplicates() # 删除重复行

# 重命名列
df.rename(columns={'old_name': 'new_name'})

# 替换值
df.replace({'old_value': 'new_value'})

# 更改数据类型
df['column'] = df['column'].astype('int32')

# 重置索引
df.reset_index(drop=True) # 丢弃原索引

数据处理

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
# 添加新列
df['new_col'] = df['A'] + df['B']

# 删除列
df.drop(columns=['A', 'B'])

# 应用函数
df['A'].apply(lambda x: x*2) # 对Series的每个元素应用函数
df.applymap(lambda x: x*2) # 对DataFrame的每个元素应用函数

# 排序
df.sort_values(by='A') # 按A列升序
df.sort_values(by='A', ascending=False) # 降序

# 排名
df['rank'] = df['A'].rank() # 为A列的值排名

# 唯一值
df['A'].unique() # A列的唯一值
df['A'].value_counts() # A列的值计数

数据分组与聚合

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
# 分组
grouped = df.groupby('E') # 按E列分组

# 聚合函数
grouped.mean() # 每组的均值
grouped.sum() # 每组的总和
grouped.size() # 每组的大小

# 多函数聚合
grouped.agg(['mean', 'std', 'count'])

# 对不同列应用不同聚合函数
grouped.agg({'A': 'mean', 'B': 'sum'})

# 转换:分组后保持原形状
df['group_mean'] = grouped['A'].transform('mean')

# 过滤
filtered = grouped.filter(lambda x: x['A'].mean() > 0.5)

时间序列

1
2
3
4
5
6
7
8
9
10
11
12
13
14
# 转换为日期时间
df['date'] = pd.to_datetime(df['date_column'])

# 设置日期索引
df.set_index('date', inplace=True)

# 时间重采样
df.resample('M').mean() # 按月重采样并求平均

# 移动窗口函数
df.rolling(window=3).mean() # 3天移动平均

# 时间偏移
df.shift(1) # 将数据向下移动一行

合并与连接

1
2
3
4
5
6
7
8
9
10
11
# 连接
pd.concat([df1, df2], axis=0) # 纵向连接
pd.concat([df1, df2], axis=1) # 横向连接

# 合并(类似SQL join)
pd.merge(df1, df2, on='key') # 内连接
pd.merge(df1, df2, on='key', how='left') # 左连接
pd.merge(df1, df2, on='key', how='outer') # 外连接

# 追加(行连接)
df1.append(df2, ignore_index=True)

高级功能

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
# 数据透视表
pivot = pd.pivot_table(df, values='D', index=['A', 'B'], columns=['C'])

# 交叉表
cross = pd.crosstab(df['A'], df['B'])

# 分箱/离散化
df['binned'] = pd.cut(df['A'], bins=3) # 等宽分箱
df['binned'] = pd.qcut(df['A'], q=4) # 等频分箱

# 字符串操作
df['str_col'].str.upper() # 转换为大写
df['str_col'].str.contains('pattern') # 包含模式
df['str_col'].str.split(' ') # 分割字符串

# 分类数据
df['cat_col'] = df['cat_col'].astype('category') # 转换为分类类型

性能优化

1
2
3
4
5
# 使用向量化操作而不是循环
# 使用 .loc 和 .iloc 而不是链式索引
# 使用适当的数据类型(如 category 用于有限值的列)
# 使用查询方法
result = df.query('A > 0.5 & B < 1.0')