模块四-数据转换与操作——23. applymap 与管道

模块四-数据转换与操作——23. applymap 与管道 23. applymap 与管道1. 概述applymap()是 DataFrame 的元素级函数应用方法可以对每个单元格应用函数。管道pipe()则是一种函数链式调用方式可以将多个数据处理步骤串联起来使代码更清晰、更易维护。importpandasaspdimportnumpyasnp# 创建示例数据dfpd.DataFrame({A:[1,2,3,4,5],B:[10,20,30,40,50],C:[100,200,300,400,500],D:[a,b,c,d,e]})print(原始数据:)print(df)2. applymap() 方法2.1 基本用法applymap()对 DataFrame 的每个元素应用函数。# 将所有元素乘以2print(每个元素乘以2:)print(df[[A,B,C]].applymap(lambdax:x*2))# 格式化所有数值df_formatteddf[[A,B,C]].applymap(lambdax:f{x:.2f})print(\n格式化:)print(df_formatted)2.2 数据类型转换# 将所有数值转为字符串df_strdf[[A,B,C]].applymap(str)print(转为字符串:)print(df_str.dtypes)# 添加前缀df_prefixeddf[[A,B,C]].applymap(lambdax:f值_{x})print(\n添加前缀:)print(df_prefixed)2.3 条件格式化# 根据值的大小进行格式化defformat_value(x):ifisinstance(x,(int,float)):ifx30:returnf**{x}**elifx10:returnf*{x}*returnstr(x)df_formatteddf.applymap(format_value)print(条件格式化:)print(df_formatted)2.4 数据清洗# 创建包含空格的示例数据df_dirtypd.DataFrame({姓名:[ 张三 ,李四, 王五 ],年龄:[25,30,28],城市:[ 北京,上海 , 广州 ]})print(脏数据:)print(df_dirty)# 批量清洗defclean_data(x):ifisinstance(x,str):returnx.strip()# 去除空格returnx df_cleandf_dirty.applymap(clean_data)print(\n清洗后:)print(df_clean)3. pipe() 管道方法3.1 基本用法pipe()允许将 DataFrame 传递给函数实现链式操作。# 定义数据处理函数defremove_outliers(df,column,threshold3):移除异常值meandf[column].mean()stddf[column].std()returndf[abs(df[column]-mean)threshold*std]defscale_column(df,column):标准化列df[column](df[column]-df[column].mean())/df[column].std()returndfdefadd_derived_columns(df):添加派生列df[A_squared]df[A]**2df[B_squared]df[B]**2returndf# 使用 pipe 链式调用df_result(df.pipe(remove_outliers,A).pipe(scale_column,B).pipe(add_derived_columns))print(管道处理结果:)print(df_result)3.2 多个参数传递# 带多个参数的函数defprocess_data(df,columns,multiplier2,add_constant0):forcolincolumns:df[col]df[col]*multiplieradd_constantreturndf# 使用 pipe 传递参数df_processeddf.pipe(process_data,[A,B,C],multiplier3,add_constant10)print(带参数处理:)print(df_processed)3.3 管道与 applymap 结合# 数据标准化处理流程defstandardize_numeric(df):标准化数值列numeric_colsdf.select_dtypes(include[int64,float64]).columnsforcolinnumeric_cols:df[col](df[col]-df[col].mean())/df[col].std()returndfdefformat_output(df):格式化输出numeric_colsdf.select_dtypes(include[int64,float64]).columns df[numeric_cols]df[numeric_cols].applymap(lambdax:f{x:.2f})returndfdefadd_summary(df):添加汇总行df.loc[汇总]df.select_dtypes(include[object]).apply(lambdax:—)returndf# 管道链df_result(df.pipe(standardize_numeric).pipe(format_output).pipe(add_summary))print(完整处理流程:)print(df_result)4. 链式操作对比4.1 传统方式 vs 管道方式# 传统方式嵌套df_tempremove_outliers(df,A)df_tempscale_column(df_temp,B)df_tempadd_derived_columns(df_temp)# 管道方式链式df_result(df.pipe(remove_outliers,A).pipe(scale_column,B).pipe(add_derived_columns))print(两种方式结果相同:,df_temp.equals(df_result))4.2 方法链 vs 管道# 方法链内置方法df_chain(df.dropna().sort_values(A).reset_index(dropTrue))# 管道自定义函数df_pipe(df.pipe(lambdax:x.dropna()).pipe(lambdax:x.sort_values(A)).pipe(lambdax:x.reset_index(dropTrue)))5. 完整示例数据清洗管道# 创建脏数据np.random.seed(42)dirty_datapd.DataFrame({id:[1,2,3,4,5,6,7,8,9,10],name:[ 张三,李四 , 王五 ,赵六,None,钱七, 孙八,周九,吴十,郑十一],age:[25,-5,30,150,28,32,0,35,130,27],salary:[5000,8000,-1000,12000,10000,None,15000,9000,25000,11000],dept:[技术,销售,技术,市场,销售,技术,None,市场,销售,技术]})print(*60)print(数据清洗管道)print(*60)print(\n原始脏数据:)print(dirty_data)# 定义清洗函数defclean_names(df):清洗姓名列ifnameindf.columns:df[name]df[name].fillna(未知)df[name]df[name].str.strip()returndfdefclean_ages(df):清洗年龄列限制在0-120之间ifageindf.columns:df[age]df[age].clip(0,120)df[age]df[age].fillna(df[age].median())returndfdefclean_salaries(df):清洗工资列ifsalaryindf.columns:df[salary]df[salary].clip(0,50000)df[salary]df[salary].fillna(df[salary].median())returndfdefclean_departments(df):清洗部门列ifdeptindf.columns:df[dept]df[dept].fillna(未知)df[dept]df[dept].str.strip()returndfdefadd_derived_columns_pipe(df):添加派生列df[age_group]pd.cut(df[age],bins[0,30,60,120],labels[青年,中年,老年])df[salary_level]pd.cut(df[salary],bins[0,5000,10000,20000,50000],labels[低,中,高,超高])returndfdefremove_invalid_rows(df):删除无效行dfdf.dropna(subset[id,name])returndf# 使用管道执行所有清洗步骤cleaned_data(dirty_data.pipe(clean_names).pipe(clean_ages).pipe(clean_salaries).pipe(clean_departments).pipe(remove_invalid_rows).pipe(add_derived_columns_pipe))print(\n清洗后数据:)print(cleaned_data)print(\n清洗前后对比:)print(f清洗前行数:{len(dirty_data)})print(f清洗后行数:{len(cleaned_data)})6. applymap vs apply vs pipe 对比方法作用对象返回值适用场景applymap()DataFrame 每个元素DataFrame元素级转换apply()Series 或 行/列Series 或 DataFrame复杂行/列计算pipe()DataFrameDataFrame函数链式调用7. 性能考虑# applymap 性能importtime large_dfpd.DataFrame(np.random.randn(1000,100))starttime.time()large_df.applymap(lambdax:x*2)print(fapplymap 耗时:{time.time()-start:.4f}秒)# 向量化更快starttime.time()large_df*2print(f向量化耗时:{time.time()-start:.4f}秒)8. 总结方法用途示例applymap(func)元素级函数df.applymap(lambda x: x*2)pipe(func)函数链式调用df.pipe(process_func)pipe(func, arg)带参数调用df.pipe(func, arg1, arg2)管道链多步骤处理df.pipe(f1).pipe(f2).pipe(f3)