二、Pandas 核心操作(全面深度版)

(一)数据创建(全场景覆盖)
import pandas as pd
import numpy as np

# 1. 从字典创建(最常用)
df = pd.DataFrame({
    'id': [1,2,3,4],
    'name': ['Alice','Bob','Charlie','David'],
    'score': [85.5, 90.0, np.nan, 78.0],
    'class': ['A','B','A','B'],
    'date': pd.date_range('2025-01-01', periods=4)
}, index=['a','b','c','d'])  # 自定义索引

# 2. 从numpy数组创建
arr = np.array([[1,2],[3,4]])
df_arr = pd.DataFrame(arr, columns=['col1','col2'], index=['row1','row2'])

# 3. 从文件创建(实战核心)
df_csv = pd.read_csv('data.csv', sep=',', header=0, na_values=['NA', '缺失'])  # CSV
df_excel = pd.read_excel('data.xlsx', sheet_name='Sheet1', usecols=['id','score'])  # Excel
df_json = pd.read_json('data.json')  # JSON

# 4. 空DataFrame
df_empty = pd.DataFrame(columns=['col1','col2'])
(二)数据探索(全方位分析)
# 1. 基础信息
df.info()  # 列类型、非空值、内存占用
df.describe(include='all')  # 数值列统计+类别列频次(include='all')
df.shape  # (行数, 列数)
df.columns  # 列名列表
df.index  # 索引列表

# 2. 缺失值分析
df.isnull().sum()  # 每列缺失值数量
df.isnull().mean()  # 每列缺失值比例
df.notnull().sum()  # 每列非空值数量

# 3. 类别列分析
df['class'].value_counts()  # 频次统计(降序)
df['class'].value_counts(normalize=True)  # 占比
df['class'].unique()  # 唯一值列表
df['class'].nunique()  # 唯一值数量

# 4. 数值列分析
df['score'].mean()  # 均值
df['score'].median()  # 中位数
df['score'].std()  # 标准差
df['score'].min()/df['score'].max()  # 最小/最大值
df['score'].quantile([0.25, 0.5, 0.75])  # 分位数
df.corr(numeric_only=True)  # 数值列相关性矩阵
(三)索引操作(高级用法)
# 1. 设置/重置索引
df_idx = df.set_index('id')  # 以id列为索引
df_idx = df_idx.reset_index()  # 重置为默认整数索引(id变回列)
df_idx = df.reset_index(drop=True)  # 重置索引并删除原索引列

# 2. 多级索引(分层索引)
df_multi = df.set_index(['class', 'id'])  # 先class后id
df_multi.loc['A']  # 取class=A的所有行
df_multi.loc[('A', 1)]  # 取class=A且id=1的行

# 3. 索引重命名/排序
df.index.rename('row_label', inplace=True)  # 索引重命名
df.sort_index(ascending=False)  # 按索引降序排序
df.sort_index(level='class', ascending=True)  # 多级索引按class排序
(四)数据筛选(极致全面)
# 1. 基础列筛选
df[['name','score']]  # 选多列
df.drop(['class'], axis=1)  # 删除列

# 2. 行筛选(布尔索引)
df[df['score'] >= 80]  # 分数≥80
df[(df['class'] == 'A') & (df['score'] > 80)]  # class=A且分数>80(&:且,|:或,~:非)
df[df['name'].isin(['Alice','Bob'])]  # 名字在列表中
df[df['score'].between(75, 90)]  # 分数在75-90之间
df[df['name'].str.contains('li')]  # 名字包含'li'(文本筛选)

# 3. 高级筛选(query/filter)
df.query('class == "A" and score > 80')  # 字符串表达式筛选(更简洁)
df.filter(items=['name','score'])  # 按列名筛选
df.filter(regex='^s')  # 按列名正则筛选(以s开头)
df.filter(like='co')  # 按列名包含'co'筛选

# 4. loc/iloc高级用法
df.loc[df['score'].notnull(), ['name','score']]  # 非空分数的姓名和分数
df.iloc[::2, [0,2]]  # 行步长2,列0和2
df.loc['a':'c', 'name':'score']  # 标签切片(左闭右闭)
df.iloc[0:3, 1:3]  # 位置切片(左闭右开)
(五)数据修改(全场景)
# 1. 列值修改
df['score'] = df['score'].fillna(df['score'].mean())  # 填充缺失值为均值
df['score_level'] = df['score'].apply(lambda x: 'Pass' if x >= 80 else 'Fail')  # 新增等级列
df['name'] = df['name'].str.upper()  # 名字转大写

# 2. 替换值
df['class'] = df['class'].replace({'A':'Class A', 'B':'Class B'})  # 替换类别
df.replace(np.nan, 0, inplace=True)  # 所有缺失值替换为0

# 3. 列重命名
df.rename(columns={'score':'math_score', 'name':'full_name'}, inplace=True)

# 4. 类型转换
df['score'] = df['score'].astype('int64')  # 浮点转整数
df['date'] = pd.to_datetime(df['date'])  # 字符串转日期
df['class'] = df['class'].astype('category')  # 转类别型(节省内存)

# 5. 批量修改(apply/applymap/map)
df[['score']] = df[['score']].apply(lambda x: x*1.1)  # 分数加10%
df.applymap(lambda x: x.strip() if isinstance(x, str) else x)  # 所有字符串去空格
df['score_level'] = df['score_level'].map({'Pass':1, 'Fail':0})  # 类别映射为数值
(六)缺失值处理(高级策略)
# 1. 填充策略
df['score'].fillna(df['score'].mean(), inplace=True)  # 均值填充
df['score'].fillna(df.groupby('class')['score'].transform('mean'), inplace=True)  # 分组均值填充
df['score'].ffill(inplace=True)  # 向前填充(用上一行值)
df['score'].bfill(inplace=True)  # 向后填充(用下一行值)
df['score'].interpolate(method='linear', inplace=True)  # 线性插值填充

# 2. 删除策略
df.dropna(axis=0, how='all')  # 删除全为缺失值的行
df.dropna(axis=0, how='any', subset=['score'])  # 删除score列有缺失的行
df.dropna(thresh=3)  # 保留至少3个非空值的行

# 3. 标记缺失值
df['score_missing'] = df['score'].isnull().astype(int)  # 新增列标记是否缺失
(七)分组聚合(高级用法)
# 1. 基础分组聚合
df_group = df.groupby('class')['score'].agg(['sum','mean','max','min']).reset_index()
df_group.columns = ['class','total_score','avg_score','max_score','min_score']  # 重命名聚合列

# 2. 命名聚合(清晰可控)
df_group = df.groupby('class').agg(
    总分=('score', 'sum'),
    平均分=('score', 'mean'),
    人数=('id', 'count')
).reset_index()

# 3. 分组过滤
df_filtered = df.groupby('class').filter(lambda x: x['score'].mean() >= 80)  # 保留平均分≥80的班级

# 4. 分组转换(保留原行数)
df['class_avg_score'] = df.groupby('class')['score'].transform('mean')  # 新增列:班级平均分
df['score_diff'] = df['score'] - df['class_avg_score']  # 分数与班级平均分的差值

# 5. 多级分组
df_multi_group = df.groupby(['class', pd.Grouper(key='date', freq='M')])['score'].mean()  # 按班级+月份分组
(八)合并与拼接(全类型)
# 1. 合并(merge):按列关联(类似SQL JOIN)
df1 = pd.DataFrame({'id': [1,2,3], 'math': [85,90,78]})
df2 = pd.DataFrame({'id': [1,2,4], 'english': [92,88,75]})

# 内连接(仅保留匹配行)
df_inner = pd.merge(df1, df2, on='id', how='inner')  # id=1,2
# 左连接(保留左表所有行)
df_left = pd.merge(df1, df2, on='id', how='left')  # id=1,2,3(english列id=3为NaN)
# 右连接(保留右表所有行)
df_right = pd.merge(df1, df2, on='id', how='right')  # id=1,2,4(math列id=4为NaN)
# 外连接(保留所有行)
df_outer = pd.merge(df1, df2, on='id', how='outer')  # id=1,2,3,4

# 2. 拼接(concat):按行/列堆叠
df3 = pd.DataFrame({'id': [5,6], 'math': [88,92]})
df_row = pd.concat([df1, df3], axis=0, ignore_index=True)  # 行拼接(重置索引)
df_col = pd.concat([df1, df2.set_index('id')], axis=1).reset_index()  # 列拼接

# 3. 追加(append):行拼接简化版(pandas 2.0后推荐用concat)
df_append = df1.append(df3, ignore_index=True)
(九)排序与排名
# 1. 按值排序
df.sort_values(by=['class','score'], ascending=[True, False], inplace=True)  # 按班级升序、分数降序

# 2. 按索引排序
df.sort_index(ascending=False, inplace=True)

# 3. 排名
df['score_rank'] = df['score'].rank(method='min', ascending=False)  # 分数排名(min:相同分数取最小排名)
# method可选:min/max/avg/first(按出现顺序)
(十)透视表与交叉表
# 1. 透视表(pivot_table):行/列/值/聚合
df_pivot = pd.pivot_table(
    df,
    values='score',
    index='class',
    columns='score_level',
    aggfunc='mean',
    fill_value=0  # 缺失值填充为0
)

# 2. 交叉表(crosstab):计数统计
df_crosstab = pd.crosstab(
    df['class'],
    df['score_level'],
    margins=True,  # 总计行/列
    normalize='index'  # 按行归一化(占比)
)
(十一)窗口函数(实战核心)
# 1. 滚动窗口(rolling)
df['score_rolling_mean'] = df['score'].rolling(window=2).mean()  # 2期滚动均值
df['score_rolling_max'] = df['score'].rolling(window=3, min_periods=1).max()  # 3期滚动最大值(至少1个值)

# 2. 指数加权窗口(ewm)
df['score_ewm'] = df['score'].ewm(alpha=0.2).mean()  # 指数加权均值(alpha=权重)

# 3. 扩展窗口(expanding)
df['score_expanding_sum'] = df['score'].expanding(min_periods=1).sum()  # 累计和
(十二)文本与时间序列处理
1. 文本处理(str访问器)
df['name'] = df['name'].str.strip()  # 去空格
df['name_length'] = df['name'].str.len()  # 名字长度
df['name_split'] = df['name'].str.split(' ')  # 拆分字符串
df['name_first_char'] = df['name'].str[0]  # 取第一个字符
df['name_contains'] = df['name'].str.contains('A', case=False)  # 包含A(忽略大小写)
df['name_replace'] = df['name'].str.replace('li', 'LI')  # 替换子串
2. 时间序列(dt访问器)
# 日期解析
df['date'] = pd.to_datetime(df['date'], format='%Y-%m-%d')

# 日期属性提取
df['year'] = df['date'].dt.year
df['month'] = df['date'].dt.month
df['day'] = df['date'].dt.day
df['weekday'] = df['date'].dt.weekday  # 星期几(0=周一)
df['is_month_end'] = df['date'].dt.is_month_end  # 是否月末

# 重采样(resample)
df_resample = df.resample('M', on='date')['score'].mean()  # 按月重采样求均值

# 时间偏移
df['date_plus_7d'] = df['date'] + pd.Timedelta(days=7)  # 加7天
df['date_plus_1m'] = df['date'] + pd.DateOffset(months=1)  # 加1个月
(十三)数据导出
# 导出为CSV
df.to_csv('output.csv', index=False, encoding='utf-8', na_rep='NA')

# 导出为Excel
df.to_excel('output.xlsx', sheet_name='Sheet1', index=False)

# 导出为JSON
df.to_json('output.json', orient='records')

# 导出为numpy数组
arr = df.to_numpy()

三、核心避坑总结

Torch 避坑
  1. view() 仅适用于连续张量,非连续需先 contiguous()
  2. transpose/permute 返回视图,修改会影响原张量;
  3. bmm 无广播,批量矩阵相乘需保证batch数一致;
  4. dot 对高维张量会展平,优先用 matmul 替代。
Pandas 避坑
  1. inplace=True 直接修改原数据,无返回值;
  2. 布尔索引中 and/or 需替换为 &/|,且条件需加括号;
  3. merge 时列名不同需用 left_on/right_on
  4. 时间序列需先解析为 datetime 类型再操作;
  5. 类别型数据用 astype('category') 可大幅节省内存。

以上内容覆盖了Pandas从基础到进阶的全场景操作,包含详细规则、示例、边界案例和避坑指南,可直接落地到实战场景中。

更多推荐