NumPy 与 Pandas 中「有无返回值函数」的易错点整理

【个人主页:玄同765

大语言模型(LLM)开发工程师中国传媒大学·数字媒体技术(智能交互与游戏设计)

**深耕领域:**大语言模型开发 / RAG知识库 / AI Agent落地 / 模型微调

**技术栈:**Python / LangChain/RAG(Dify+Redis+Milvus)| SQL/NumPy | FastAPI+Docker ️

**工程能力:**专注模型工程化部署、知识库构建与优化,擅长全流程解决方案

「让AI交互更智能,让技术落地更高效」

欢迎技术探讨/项目合作! 关注我,解锁大模型与智能交互的无限可能!

在使用 NumPy 和 Pandas 进行数据分析和处理时,「函数是否有返回值、是否会修改原对象」是一个高频易错点 ------ 很多人会因混淆这两类函数导致数据被意外修改、操作无响应或结果不正确。本文将通过功能分类表格实战代码示例,系统整理 NumPy 与 Pandas 中典型的有无返回值函数,帮助读者避免此类错误。


一、问题引入:一个真实场景的错误

假设你正在处理一份客户购买数据,需要对部分列进行归一化处理:

复制代码
import pandas as pd
import numpy as np

# 生成模拟数据
data = pd.DataFrame({
    'customer_id': [1, 2, 3, 4, 5],
    'product_id': [101, 102, 101, 103, 102],
    'quantity': [5, 3, 2, 1, 4],
    'price': [10.5, 20.0, 10.5, 30.0, 20.0]
})

# 归一化quantity列
# 错误做法:直接调用DataFrame的apply方法,未赋值
data['quantity'].apply(lambda x: (x - np.min(data['quantity'])) / (np.max(data['quantity']) - np.min(data['quantity'])))

# 打印结果,发现quantity列未变化
print(data['quantity'])

错误原因DataFrame.apply()方法会返回一个新的 Series 对象,不会直接修改原列。正确做法是将返回值赋值给原列或新列。


二、NumPy 中有无返回值函数整理

NumPy 中的函数按是否修改原数组 分为两类:返回新数组的函数直接修改原数组的函数 (通常以_结尾,称为「原地操作函数」)。

2.1 NumPy 功能分类表格

功能分类 函数名 功能 是否有返回值 原数组是否改变 代码示例
数组创建 np.array 从列表 / 元组创建数组 arr = np.array([1, 2, 3])
np.zeros 创建全零数组 arr = np.zeros(5)
np.ones 创建全一数组 arr = np.ones(5)
形状修改 arr.reshape 改变数组形状 new_arr = arr.reshape(2, 3)
arr.resize 改变数组形状(可原地) 否(无返回) 是(原地修改) arr.resize(2, 3)
arr.T 数组转置 new_arr = arr.T
数据操作 np.add 数组加法(向量化) new_arr = np.add(arr1, arr2)
arr1 + arr2 数组加法(运算符重载) new_arr = arr1 + arr2
arr.fill 数组填充值 否(无返回) 是(原地修改) arr.fill(0)
np.where 条件索引 new_arr = np.where(arr > 0, arr, 0)
统计计算 np.sum 数组求和 sum_result = np.sum(arr)
np.mean 数组平均值 mean_result = np.mean(arr)
np.max 数组最大值 max_result = np.max(arr)
原地操作 arr += arr2 原地加法 否(无返回) 是(原地修改) arr += arr2
arr.sort 原地排序 否(无返回) 是(原地修改) arr.sort()
arr.flatten 数组扁平化(返回拷贝) new_arr = arr.flatten()
arr.ravel 数组扁平化(返回视图) new_arr = arr.ravel()

2.2 NumPy 实战易错点示例

示例 1:混淆 reshape 与 resize
复制代码
import numpy as np

# 创建数组
arr = np.array([1, 2, 3, 4, 5, 6])

# reshape:返回新数组,原数组不变
new_arr1 = arr.reshape(2, 3)
print(f"reshape后原数组:{arr}")  # [1 2 3 4 5 6](未变化)
print(f"reshape后新数组:\n{new_arr1}")

# resize:原地修改,无返回值
arr.resize(2, 3)
print(f"resize后原数组:\n{arr}")  # [[1 2 3] [4 5 6]](已变化)
示例 2:混淆 sort 与 sorted
复制代码
import numpy as np

# 创建数组
arr = np.array([3, 1, 4, 1, 5, 9, 2, 6])

# sorted:返回新数组,原数组不变
new_arr1 = sorted(arr)
print(f"sorted后原数组:{arr}")  # [3 1 4 1 5 9 2 6](未变化)
print(f"sorted后新数组:{new_arr1}")

# arr.sort:原地修改,无返回值
arr.sort()
print(f"arr.sort后原数组:{arr}")  # [1 1 2 3 4 5 6 9](已变化)

三、Pandas 中有无返回值函数整理

Pandas 中的函数同样分为返回新对象的函数直接修改原对象的函数 (通常有inplace=True参数)。Pandas 的函数更多,我们按Series 操作DataFrame 操作分类整理。

3.1 Series 操作分类表格

功能分类 函数名 功能 是否有返回值 原对象是否改变(默认) 代码示例
数据操作 s.apply 应用自定义函数 new_s = s.apply(lambda x: x*2)
s.map 应用字典 / Series / 函数 new_s = s.map({1: 'A', 2: 'B'})
s.replace 替换值 new_s = s.replace(1, 'A')
数据过滤 s[s > 0] 条件过滤 new_s = s[s > 0]
统计计算 s.sum 求和 sum_result = s.sum()
s.mean 平均值 mean_result = s.mean()
原地操作 s.fillna 填充缺失值 是(默认) 否(默认) new_s = s.fillna(0)s.fillna(0, inplace=True)
s.dropna 删除缺失值 是(默认) 否(默认) new_s = s.dropna()s.dropna(inplace=True)
s.sort_values 排序 是(默认) 否(默认) new_s = s.sort_values()s.sort_values(inplace=True)

3.2 DataFrame 操作分类表格

功能分类 函数名 功能 是否有返回值 原对象是否改变(默认) 代码示例
数据操作 df.apply 应用自定义函数 new_df = df.apply(lambda x: x*2)
df.applymap 应用自定义函数到每个元素 new_df = df.applymap(lambda x: str(x))
df.pipe 链式操作 new_df = df.pipe(lambda x: x[x['quantity'] > 0])
形状修改 df.drop 删除列 / 行 是(默认) 否(默认) new_df = df.drop('price', axis=1)df.drop('price', axis=1, inplace=True)
df.rename 重命名列 / 行 是(默认) 否(默认) new_df = df.rename({'customer_id': 'id'}, axis=1)df.rename({'customer_id': 'id'}, axis=1, inplace=True)
数据过滤 df[df['quantity'] > 0] 条件过滤 new_df = df[df['quantity'] > 0]
合并 / 拼接 pd.concat 合并 DataFrame/Series new_df = pd.concat([df1, df2], axis=0)
pd.merge 合并 DataFrame(类似 SQL) new_df = pd.merge(df1, df2, on='customer_id')
原地操作 df.fillna 填充缺失值 是(默认) 否(默认) new_df = df.fillna(0)df.fillna(0, inplace=True)
df.dropna 删除缺失值 是(默认) 否(默认) new_df = df.dropna()df.dropna(inplace=True)
df.sort_values 排序 是(默认) 否(默认) new_df = df.sort_values('quantity')df.sort_values('quantity', inplace=True)

3.3 Pandas 实战易错点示例

示例 1:未使用 inplace=True 参数
复制代码
import pandas as pd

# 创建DataFrame
data = pd.DataFrame({
    'customer_id': [1, 2, 3, 4, 5],
    'product_id': [101, 102, 101, 103, 102],
    'quantity': [5, 3, 2, 1, 4],
    'price': [10.5, 20.0, 10.5, 30.0, 20.0]
})

# 错误做法:直接调用drop方法,未赋值或使用inplace=True
data.drop('price', axis=1)

# 打印结果,发现price列未变化
print(data.columns)  # Index(['customer_id', 'product_id', 'quantity', 'price'], dtype='object')

# 正确做法1:赋值给新DataFrame
new_data1 = data.drop('price', axis=1)
print(new_data1.columns)  # Index(['customer_id', 'product_id', 'quantity'], dtype='object')

# 正确做法2:使用inplace=True参数
data.drop('price', axis=1, inplace=True)
print(data.columns)  # Index(['customer_id', 'product_id', 'quantity'], dtype='object')
示例 2:混淆 apply 与 applymap
复制代码
import pandas as pd
import numpy as np

# 创建DataFrame
data = pd.DataFrame({
    'customer_id': [1, 2, 3, 4, 5],
    'product_id': [101, 102, 101, 103, 102],
    'quantity': [5, 3, 2, 1, 4],
    'price': [10.5, 20.0, 10.5, 30.0, 20.0]
})

# apply:应用到列(默认axis=0)或行(axis=1)
total_price = data.apply(lambda x: x['quantity'] * x['price'] if x.name == 'total' else x, axis=0)  # 错误用法,apply默认作用于列
total_price = data.apply(lambda x: x['quantity'] * x['price'], axis=1)  # 正确用法,作用于行
data['total_price'] = total_price
print(data['total_price'])

# applymap:应用到每个元素
data_str = data.applymap(lambda x: str(x))
print(data_str.dtypes)  # 所有列都是object类型

四、总结

通过本文的整理,我们可以看出 NumPy 与 Pandas 中「有无返回值函数」的规律:

  1. NumPy :大部分函数会返回新数组,不会修改原数组;原地操作函数通常以_结尾,无返回值,会直接修改原数组。
  2. Pandas :大部分函数会返回新对象,不会修改原对象;原地操作需要使用inplace=True参数,使用后无返回值,会直接修改原对象。

在实际开发中,我们应该:

  1. 优先使用返回新对象的函数,这样可以保留原数据,便于调试和错误恢复。
  2. 如果需要节省内存或必须修改原对象,可以使用原地操作函数,但要确保操作的正确性。
  3. 对不熟悉的函数,可以先查看官方文档或进行小范围测试,确认其是否有返回值、是否会修改原对象。
相关推荐
九.九8 小时前
ops-transformer:AI 处理器上的高性能 Transformer 算子库
人工智能·深度学习·transformer
春日见8 小时前
拉取与合并:如何让个人分支既包含你昨天的修改,也包含 develop 最新更新
大数据·人工智能·深度学习·elasticsearch·搜索引擎
恋猫de小郭8 小时前
AI 在提高你工作效率的同时,也一直在增加你的疲惫和焦虑
前端·人工智能·ai编程
YJlio8 小时前
1.7 通过 Sysinternals Live 在线运行工具:不下载也能用的“云端工具箱”
c语言·网络·python·数码相机·ios·django·iphone
deephub8 小时前
Agent Lightning:微软开源的框架无关 Agent 训练方案,LangChain/AutoGen 都能用
人工智能·microsoft·langchain·大语言模型·agent·强化学习
l1t9 小时前
在wsl的python 3.14.3容器中使用databend包
开发语言·数据库·python·databend
大模型RAG和Agent技术实践9 小时前
从零构建本地AI合同审查系统:架构设计与流式交互实战(完整源代码)
人工智能·交互·智能合同审核
老邋遢9 小时前
第三章-AI知识扫盲看这一篇就够了
人工智能
互联网江湖9 小时前
Seedance2.0炸场:长短视频们“修坝”十年,不如AI放水一天?
人工智能
PythonPioneer9 小时前
在AI技术迅猛发展的今天,传统职业该如何“踏浪前行”?
人工智能