当前位置: 首页 > news >正文

Pandas 高级技巧与最佳实践

Pandas 高级技巧与最佳实践

🎯目标:掌握 Pandas 的进阶用法和性能优化技巧,成为 Pandas 高手。


11.1 性能优化

11.1.1 向量化 vs 循环

importpandasaspdimportnumpyasnpimporttime# 创建大数据集n=1_000_000df=pd.DataFrame({'A':np.random.randn(n),'B':np.random.randn(n)})# ❌ 慢:用循环defloop_add(df):result=[]foriinrange(len(df)):result.append(df.iloc[i]['A']+df.iloc[i]['B'])returnresult start=time.time()loop_result=loop_add(df)print(f"循环耗时:{time.time()-start:.2f}秒")# ✅ 快:用向量化start=time.time()vector_result=df['A']+df['B']print(f"向量化耗时:{time.time()-start:.4f}秒")

💡黄金法则:永远不要对 DataFrame 用循环!

11.1.2 使用合适的数据类型

# 创建示例数据df=pd.DataFrame({'int64_col':np.random.randint(0,100,1000000),'float64_col':np.random.randn(1000000),'category_col':np.random.choice(['A','B','C','D'],1000000),'object_col':np.random.choice(['北京','上海','广州','深圳'],1000000)})print("原始内存使用:")print(df.memory_usage(deep=True).sum()/1024**2,"MB")# 🌟 优化数据类型df_optimized=df.copy()df_optimized['int64_col']=df_optimized['int64_col'].astype('int32')# int64 → int32df_optimized['float64_col']=df_optimized['float64_col'].astype('float32')# float64 → float32df_optimized['category_col']=df_optimized['category_col'].astype('category')df_optimized['object_col']=df_optimized['object_col'].astype('category')print("\n优化后内存使用:")print(df_optimized.memory_usage(deep=True).sum()/1024**2,"MB")

11.1.3 使用 eval 和 query

# 创建大数据df=pd.DataFrame(np.random.randn(100000,4),columns=['A','B','C','D'])# 🌟 eval:高效计算# 普通方式df['E']=df['A']+df['B']*df['C']-df['D']# eval 方式(更快)df['E']=df.eval('A + B * C - D')# 🌟 query:高效筛选# 普通方式result=df[(df['A']>0)&(df['B']<0)]# query 方式(更快)result=df.query('A > 0 and B < 0')

11.2 内存优化

11.2.1 分块读取大文件

# 🌟 分块读取 CSVchunk_size=100000chunks=[]forchunkinpd.read_csv('large_file.csv',chunksize=chunk_size):# 处理每个 chunkprocessed=chunk[chunk['value']>0]# 示例处理chunks.append(processed)# 合并结果df=pd.concat(chunks,ignore_index=True)

11.2.2 使用迭代器

# 🌟 迭代器方式读取forchunkinpd.read_csv('large_file.csv',chunksize=10000):forrowinchunk.itertuples():# 处理每一行pass

11.2.3 删除中间变量

# ❌ 内存占用大df1=pd.read_csv('data.csv')df2=df1[df1['A']>0]df3=df2.groupby('B').sum()df4=df3.reset_index()# ✅ 及时释放内存df=pd.read_csv('data.csv')df=df[df['A']>0]df=df.groupby('B').sum()df=df.reset_index()

11.3 链式操作

11.3.1 方法链式调用

# ❌ 传统方式(多个变量)df=pd.read_csv('data.csv')df=df[df['A']>0]df=df.dropna()df=df.assign(C=lambdax:x['A']+x['B'])df=df.groupby('D').sum()# ✅ 链式操作(一个表达式)result=(pd.read_csv('data.csv').query('A > 0').dropna().assign(C=lambdax:x['A']+x['B']).groupby('D').sum().reset_index())

11.3.2 使用 pipe

# 🌟 自定义函数deffilter_positive(df,col):returndf[df[col]>0]defadd_ratio(df,num_col,den_col):returndf.assign(ratio=df[num_col]/df[den_col])# 🌟 使用 pipe 链式调用result=(pd.read_csv('data.csv').pipe(filter_positive,'sales').pipe(add_ratio,'profit','sales').groupby('category').agg({'ratio':'mean'}))

11.4 实用技巧合集

11.4.1 快速查看数据

df=pd.DataFrame(np.random.randn(1000,10),columns=[f'col_{i}'foriinrange(10)])# 🌟 快速查看print(df.head())# 前5行print(df.tail())# 后5行print(df.sample(5))# 随机5行print(df.describe())# 统计摘要print(df.info())# 数据信息print(df.dtypes)# 数据类型print(df.shape)# 形状print(df.columns.tolist())# 列名列表print(df.index)# 索引

11.4.2 快速选择数据

# 🌟 快速选择# 选择数值列numeric_cols=df.select_dtypes(include=[np.number]).columns# 选择字符串列string_cols=df.select_dtypes(include=['object']).columns# 选择列名包含特定字符串的列df.filter(like='col_1')# 选择列名匹配正则表达式的列df.filter(regex='col_[0-5]')

11.4.3 快速处理缺失值

df=pd.DataFrame({'A':[1,2,np.nan,4],'B':[5,np.nan,np.nan,8],'C':[9,10,11,12]})# 🌟 快速查看缺失值print(df.isnull().sum())# 每列缺失值数量print(df.isnull().sum().sum())# 总缺失值数量print(df.isnull().mean()*100)# 缺失值百分比# 🌟 快速删除print(df.dropna())# 删除包含缺失值的行print(df.dropna(axis=1))# 删除包含缺失值的列print(df.dropna(thresh=2))# 保留至少2个非缺失值的行# 🌟 快速填充print(df.fillna(0))# 用0填充print(df.fillna(df.mean()))# 用均值填充print(df.fillna(method='ffill'))# 前向填充print(df.fillna(method='bfill'))# 后向填充

11.4.4 快速数据转换

df=pd.DataFrame({'A':[1,2,3,4],'B':['a','b','c','d'],'C':[1.5,2.5,3.5,4.5]})# 🌟 类型转换print(df.astype({'A':'float64','C':'int32'}))# 🌟 字符串操作df['B_upper']=df['B'].str.upper()df['B_len']=df['B'].str.len()# 🌟 数值操作df['A_squared']=df['A'].pow(2)df['A_log']=np.log(df['A'])# 🌟 条件赋值df['A_category']=np.where(df['A']>2,'high','low')

11.5 调试技巧

11.5.1 查看中间结果

# 🌟 使用 pipe 查看中间结果defdebug_print(df,message=""):print(f"\n{message}")print(f"Shape:{df.shape}")print(df.head())returndf result=(pd.read_csv('data.csv').pipe(debug_print,"After loading").query('A > 0').pipe(debug_print,"After filtering").groupby('B').sum().pipe(debug_print,"After grouping"))

11.5.2 使用选项设置

# 🌟 显示设置pd.set_option('display.max_rows',100)# 最大显示行数pd.set_option('display.max_columns',50)# 最大显示列数pd.set_option('display.width',200)# 显示宽度pd.set_option('display.float_format','{:.2f}'.format)# 浮点数格式# 🌟 重置设置pd.reset_option('all')

11.6 常见陷阱与解决方案

11.6.1 SettingWithCopyWarning

df=pd.DataFrame({'A':[1,2,3],'B':[4,5,6]})# ❌ 警告:SettingWithCopyWarningdf[df['A']>1]['B']=100# 可能不生效# ✅ 正确方式1:使用 locdf.loc[df['A']>1,'B']=100# ✅ 正确方式2:使用 copysubset=df[df['A']>1].copy()subset['B']=100

11.6.2 索引问题

# ❌ 问题:重置索引后丢失原索引df=df.reset_index()# ✅ 保留原索引df=df.reset_index(drop=False)# 保留为列df=df.reset_index(drop=True)# 完全删除

11.6.3 类型推断问题

# ❌ 问题:整数列有缺失值会变成 floatdf=pd.DataFrame({'A':[1,2,None,4]})print(df.dtypes)# float64# ✅ 使用 nullable 整数类型df=pd.DataFrame({'A':pd.array([1,2,None,4],dtype=pd.Int64Dtype())})print(df.dtypes)# Int64

11.7 与其他库的集成

11.7.1 NumPy

# 🌟 DataFrame 和 NumPy 数组互转df=pd.DataFrame(np.random.randn(100,4),columns=['A','B','C','D'])arr=df.values# 转 NumPy 数组df2=pd.DataFrame(arr,columns=['A','B','C','D'])# 转 DataFrame# 🌟 使用 NumPy 函数print(np.sqrt(df))print(np.log(df))print(np.mean(df,axis=0))

11.7.2 Matplotlib

importmatplotlib.pyplotasplt df=pd.DataFrame({'A':np.random.randn(100).cumsum(),'B':np.random.randn(100).cumsum()},index=pd.date_range('2024-01-01',periods=100))# 🌟 快速绘图df.plot(figsize=(10,6))plt.title('Time Series Plot')plt.show()# 🌟 子图df.plot(subplots=True,figsize=(10,8))plt.show()

11.7.3 Scikit-learn

fromsklearn.preprocessingimportStandardScalerfromsklearn.model_selectionimporttrain_test_split df=pd.DataFrame(np.random.randn(100,4),columns=['A','B','C','D'])# 🌟 数据预处理scaler=StandardScaler()df_scaled=pd.DataFrame(scaler.fit_transform(df),columns=df.columns,index=df.index)# 🌟 划分训练集和测试集train,test=train_test_split(df,test_size=0.2)

11.8 本章小结

核心要点

性能优化

  • 使用向量化操作,避免循环
  • 选择合适的数据类型
  • 使用 eval 和 query

内存优化

  • 分块读取大文件
  • 及时删除中间变量
  • 使用 category 类型

链式操作

  • 使用方法链提高可读性
  • 使用 pipe 自定义函数

实用技巧

  • 快速查看数据
  • 快速选择和处理数据
  • 调试技巧

避免陷阱

  • SettingWithCopyWarning
  • 索引问题
  • 类型推断问题

最佳实践清单

  • 使用向量化操作
  • 选择合适的数据类型
  • 使用链式操作提高可读性
  • 及时释放内存
  • 使用 loc 进行赋值
  • 处理大文件时使用分块读取
  • 使用 pipe 进行调试

http://www.jsqmd.com/news/975820/

相关文章:

  • 办理经营性贷款需要哪些资质材料
  • 2026哈尔滨二奢包包高价回收攻略,吃透行情多卖钱 - 奢侈品回收测评
  • 2026年05月广佛团建行业发展趋势洞察|广州市启恩企业管理咨询有限公司
  • 2026海关事务咨询服务哪家专业及选择参考 - 品牌排行榜
  • DSP聚合网关架构解析:基于MSC8101与MPC8260的媒体流高效处理
  • 上海专业AI SEO服务机构推荐: 技术能力、案例真实性与交付透明度综合评测 - 品牌排行榜
  • 智能体为什么落地难?
  • VMware Workstation Pro 17 虚拟机添加SCSI硬盘后,fdisk -l 不显示?试试这个手动扫描命令
  • 执笔赴盛夏,逐梦向长空|沈阳昊天环宇无人机致全体高考学子
  • 告别玄学调参:一篇讲透ArcGIS中DEM坐标系与坡度精度的关系
  • 从STP到RSTP:一次配置搞定思科交换机多VLAN的根桥选举(附优先级设置避坑指南)
  • 5B参数如何实现720P视频生成?深度解析Wan2.2-TI2V-5B的技术突破与实践应用
  • 2026年国内工业水性漆品牌综合实力解析 - 品牌排行榜
  • 为什么说ArduPilot是开源自动驾驶系统的终极解决方案?
  • 维也纳工业大学与KR Labs联手出击:让AI回答学术问题不再“瞎编“
  • 解决Windows 10/11运行《红色警戒2》的5大核心痛点:原生版配置深坑与一键集成优化版的深度横向测评
  • 百度自然排名靠后怎么用GEO优化补救
  • Jasminum插件深度解析:如何通过中文文献管理提升学术研究效率
  • 英国2026留学中介哪家好?八家优选全面盘点口碑王者 - 资讯纵览
  • SQLite图形化工具选哪个?深度对比SQLite Expert与DB Browser的优缺点和适用场景
  • Docker部署HomeLists家庭库存管理工具
  • 2026年称重传感器厂家推荐排行榜:防水/悬臂梁/柱式/化工/防爆称重传感器优质品牌之选! - 资讯纵览
  • 登录、注册页面学习
  • 2026风幕柜水果展示柜敞开式保鲜源头工厂入选实力品牌 - 资讯焦点
  • EmojiOne Color:让表情符号从黑白走向彩色的完整解决方案
  • 【保姆级教程】!两小时入门TurtleBot3 SLAM建图+自主导航+避障实战教程(附完整源码)
  • 炉石传说HsMod插件:55项功能解锁你的终极游戏体验
  • 避开部署雷区!OpenClaw Windows 版安装设置全讲解(包含安装包)
  • 推理加速三板斧:KV Cache、PagedAttention、Continuous Batching
  • 基于i.MX RT1060与DMA实现高速RS-485通信的工程实践