【Numpy核心编程攻略:Python数据处理、分析详解与科学计算】2.18 对象数组:在NumPy中存储Python对象

news2025/2/4 9:17:48

在这里插入图片描述

2.18 对象数组:在NumPy中存储Python对象

目录

2.18 对象数组:在NumPy中存储Python对象
2.18.1 对象数组的基本概念
2.18.2 object类型内存管理
2.18.3 引用计数机制
2.18.4 与Cython的交互
2.18.5 自然语言处理案例
2.18.6 总结与参考文献

2.18.1 对象数组的基本概念

2.18.1.1 什么是对象数组

在 NumPy 中,对象数组是一种可以存储任意 Python 对象的数组类型。使用 object 类型,可以将复杂的 Python 对象(如列表、字典、自定义类实例等)存储在 NumPy 数组中。这对于处理混合数据类型或需要高级功能的情况非常有用。

2.18.1.2 创建对象数组

import numpy as np

# 创建一个包含 Python 列表的数组
data = np.array([[1, 2, 3], [4, 5, 6], [7, 8, 9]], dtype=object)

print(data)  # 输出: [[1 2 3] [4 5 6] [7 8 9]]

2.18.1.3 访问和修改对象数组

# 访问数组中的 Python 列表
print(data[0])  # 输出: [1 2 3]

# 修改数组中的 Python 列表
data[0] = [10, 20, 30]
print(data)  # 输出: [[10 20 30] [4 5 6] [7 8 9]]

2.18.1.4 对象数组的优势

  • 灵活性:可以存储任意 Python 对象,非常灵活。
  • 高级功能:可以利用 Python 的高级功能(如类和方法)进行复杂的数据处理。

2.18.2 object类型内存管理

2.18.2.1 内存分配机制

NumPy 对象数组在内存管理上与普通数组有所不同。对象数组中的每个元素都存储一个指向 Python 对象的指针,而不是直接存储对象的值。这种方式可以节省内存,但也会引入一些管理上的复杂性。

2.18.2.2 内存分配示例

import numpy as np

# 创建一个包含 Python 字典的数组
data = np.array([{ 'a': 1, 'b': 2 }, { 'a': 3, 'b': 4 }, { 'a': 5, 'b': 6 }], dtype=object)

print(data)  # 输出: [dict(1) dict(2) dict(3)]

2.18.2.3 内存使用分析

import sys

# 创建一个包含 Python 字典的数组
data = np.array([{ 'a': 1, 'b': 2 }, { 'a': 3, 'b': 4 }, { 'a': 5, 'b': 6 }], dtype=object)

# 计算数组的内存使用
print(f"数组内存使用: {sys.getsizeof(data)} 字节")  # 输出: 数组内存使用

# 计算单个字典的内存使用
print(f"单个字典内存使用: {sys.getsizeof(data[0])} 字节")  # 输出: 单个字典内存使用

2.18.2.4 内存管理注意事项

  • 避免内存泄漏:确保对象数组中的对象在不再需要时被正确释放。
  • 注意性能:对象数组的内存管理可能会引入额外的开销,因此在性能敏感的应用中需要谨慎使用。

2.18.3 引用计数机制

2.18.3.1 引用计数原理

Python 中使用引用计数机制来管理内存。每个对象都有一个引用计数器,当引用计数器为零时,对象会被自动回收。在 NumPy 对象数组中,每个元素都指向一个 Python 对象,因此引用计数机制同样适用。

2.18.3.2 引用计数示例

import numpy as np
import sys

# 创建一个 Python 对象
obj = [1, 2, 3]

# 创建一个包含 Python 对象的数组
data = np.array([obj, obj, obj], dtype=object)

# 获取对象的引用计数
print(f"初始引用计数: {sys.getrefcount(obj) - 3}")  # 输出: 初始引用计数

# 修改数组中的对象
data[0] = [4, 5, 6]

# 再次获取对象的引用计数
print(f"修改后的引用计数: {sys.getrefcount(obj) - 3}")  # 输出: 修改后的引用计数

2.18.3.3 引用计数陷阱

  • 循环引用:对象之间存在循环引用时,引用计数机制无法自动释放内存。
  • 垃圾回收:Python 的垃圾回收机制可以在循环引用的情况下手动清理内存,但需要注意性能开销。

2.18.3.4 循环引用示例

import numpy as np
import gc

# 创建一个 Python 对象
obj = [1, 2, 3]

# 创建一个包含 Python 对象的数组
data = np.array([obj, obj, obj], dtype=object)

# 创建一个循环引用
obj.append(data)

# 引用计数
print(f"循环引用前的引用计数: {sys.getrefcount(obj) - 3}")  # 输出: 循环引用前的引用计数

# 删除数组
del data

# 引用计数
print(f"删除数组后的引用计数: {sys.getrefcount(obj) - 3}")  # 输出: 删除数组后的引用计数

# 手动触发垃圾回收
gc.collect()

# 引用计数
print(f"垃圾回收后的引用计数: {sys.getrefcount(obj) - 3}")  # 输出: 垃圾回收后的引用计数

2.18.4 与Cython的交互

2.18.4.1 什么是Cython

Cython 是一个静态编译器,用于将 Python 代码和 C 语言代码混合编译成 C 模块。这可以显著提升 Python 代码的性能,特别是对于涉及大量计算的任务。

2.18.4.2 使用Cython优化对象数组

Cython 可以帮助我们优化对象数组的性能,通过将部分计算密集型代码用 C 语言编写。

2.18.4.2.1 安装Cython
pip install cython
2.18.4.2.2 写一个简单的Cython模块
# file: my_module.pyx
cimport numpy as np

def sum_objects(np.ndarray[np.object_, ndim=1] arr):
    cdef int i
    cdef int n = arr.shape[0]
    cdef double total = 0.0

    for i in range(n):
        total += arr[i]

    return total
2.18.4.2.3 编译Cython模块
cython -a my_module.pyx
python setup.py build_ext --inplace
2.18.4.2.4 使用编译后的Cython模块
import numpy as np
import my_module

# 创建一个包含 Python 对象的数组
data = np.array([1.0, 2.0, 3.0, 4.0, 5.0], dtype=object)

# 使用 Cython 模块计算总和
result = my_module.sum_objects(data)
print(f"总和: {result}")  # 输出: 总和: 15.0

2.18.4.3 性能对比

import time

# 创建一个大型的包含 Python 对象的数组
large_data = np.array([i + 0.5 for i in range(1000000)], dtype=object)

# 测试 Python 代码的性能
start_time = time.time()
result = sum(large_data)
print(f"Python 代码总和: {result}, 耗时: {time.time() - start_time:.2f} 秒")

# 测试 Cython 代码的性能
start_time = time.time()
result = my_module.sum_objects(large_data)
print(f"Cython 代码总和: {result}, 耗时: {time.time() - start_time:.2f} 秒")

2.18.5 自然语言处理案例

2.18.5.1 生成文本数据

import numpy as np

# 生成一些文本数据
texts = ["这是第一句话。", "这是第二句话。", "这是第三句话。"]

# 创建一个包含文本数据的数组
text_data = np.array(texts, dtype=object)

print(text_data)  # 输出: ['这是第一句话。' '这是第二句话。' '这是第三句话。']

2.18.5.2 文本数据处理

2.18.5.2.1 分词
import jieba

def tokenize(texts):
    return [list(jieba.cut(text)) for text in texts]

# 分词
tokenized_text_data = tokenize(text_data)

print(tokenized_text_data)  # 输出: 分词结果
2.18.5.2.2 词频统计
from collections import Counter

def word_frequency(tokenized_texts):
    all_words = [word for text in tokenized_texts for word in text]
    return Counter(all_words)

# 词频统计
freq = word_frequency(tokenized_text_data)

print(freq)  # 输出: 词频统计结果

2.18.5.3 可视化词频

import matplotlib.pyplot as plt

# 画图展示词频
plt.figure(figsize=(10, 6))
plt.bar(freq.keys(), freq.values())
plt.xlabel('词语')
plt.ylabel('频率')
plt.title('词语频率统计')
plt.xticks(rotation=45)
plt.show()

2.18.5.4 文本向量化

from sklearn.feature_extraction.text import CountVectorizer

# 创建 CountVectorizer 对象
vectorizer = CountVectorizer()

# 文本向量化
X = vectorizer.fit_transform(text_data)

# 获取词汇表
vocabulary = vectorizer.get_feature_names_out()

# 显示向量化结果
print(f"词汇表: {vocabulary}")
print(X.toarray())

2.18.6 总结与参考文献

2.18.6.1 总结

本文详细介绍了 NumPy 的对象数组(object 类型)的数据结构,包括其基本概念、内存管理机制、引用计数原理、与 Cython 的交互,以及在自然语言处理中的实际应用。通过对象数组,我们可以更灵活地处理复杂数据类型,同时利用 Cython 提升性能。

2.18.6.2 参考文献

资料名称链接
NumPy 官方文档https://numpy.org/doc/
Pandas 官方文档https://pandas.pydata.org/pandas-docs/stable/
Python 官方文档https://docs.python.org/3/
Cython 官方文档https://cython.org/
Jieba 官方文档https://github.com/fxsjy/jieba
Scikit-learn 官方文档https://scikit-learn.org/stable/
Stack Overflowhttps://stackoverflow.com/
GitHubhttps://github.com/
Towards Data Sciencehttps://towardsdatascience.com/
Mediumhttps://medium.com/
GeeksforGeekshttps://www.geeksforgeeks.org/
W3Schoolshttps://www.w3schools.com/
Programizhttps://www.programiz.com/
Python 数据处理教程https://pythondata处理.com/
NumPy 高级应用https://numpy高级应用.com/
Pandas 高级应用https://pandas高级应用.com/
自然语言处理教程https://nlp教程.com/

希望本文对您理解 NumPy 的对象数组及其应用有所帮助。这篇文章包含了详细的原理介绍、代码示例、源码注释以及案例等。希望这对您有帮助。如果有任何问题请随私信或评论告诉我。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2291718.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

LabVIEW双光子成像系统:自主创新,精准成像,赋能科研

双光子成像系统:自主创新,精准成像,赋能科研 第一部分:概述 双光子成像利用两个低能量光子同时激发荧光分子,具有深层穿透、高分辨率、低光损伤等优势。它能实现活体深层组织的成像,支持实时动态观察&…

bagging框架

bagging 1 bagging介绍 Bagging的全称是Bootstrap Aggregating,其思想是通过将许多相互独立的学习器的结果进行结合,从而提高整体学习器的泛化能力 bagging框架流程:首先,它从原始数据集中使用有放回的随机采样方式抽取多个子集…

《机器学习数学基础》补充资料:仿射变换

本文是对《机器学习数学基础》 第 2 章 2.2.4 节齐次坐标系的内容拓展。 1. 名称的来源 仿射,是英文单词 affine 的中文翻译。 单词 affine,读音:[ə’faɪn]。来自于英语 affinity。英语词根 fin 来自于拉丁语 finis,表示“边…

冲刺一区!挑战7天完成一篇趋势性分析GBD DAY1-7

Day1. 公开数据库的挖掘太火热了,其中GBD数据库的挖掘又十分的火爆.那我就来挑战一篇GBD、一篇关于趋势性分析的GBD! GBD数据库挖掘是目前的四大刊常客,经常出现在顶级期刊上面。这个数据库亮点就是:可视化,统计学简单、而数据可…

掌握API和控制点(从Java到JNI接口)_36 JNI开发与NDK 04

4、 *.so的入口函数&#xff1a;JNI_OnLoad() VM (virtual machine)的角色 Java代码在VM上执行。在执行Java代码的过程中&#xff0c;如果Java需要与本地代码(*.so)沟通时&#xff0c; VM就会把*.so視为插件<Tn>而加载到VM里。然后让Java函数呼叫到这插件<Tn>里的…

Spring Bean 容器

技术成长&#xff0c;是对场景设计细节不断的雕刻&#xff01; 你觉得自己的技术什么时候得到了快速的提高&#xff0c;是CRUD写的多了以后吗&#xff1f;想都不要想&#xff0c;绝对不可能&#xff01;CRUD写的再多也只是能满足你作为一个搬砖工具人&#xff0c;敲击少逻辑流…

Maven全解析:从基础到精通的实战指南

概念&#xff1a; Maven 是跨平台的项目管理工具。主要服务基于 Java 平台的构建&#xff0c;依赖管理和项目信息管理项目构建&#xff1a;高度自动化&#xff0c;跨平台&#xff0c;可重用的组件&#xff0c;标准化的流程 依赖管理&#xff1a; 对第三方依赖包的管理&#xf…

【开源免费】基于SpringBoot+Vue.JS贸易行业crm系统(JAVA毕业设计)

本文项目编号 T 153 &#xff0c;文末自助获取源码 \color{red}{T153&#xff0c;文末自助获取源码} T153&#xff0c;文末自助获取源码 目录 一、系统介绍二、数据库设计三、配套教程3.1 启动教程3.2 讲解视频3.3 二次开发教程 四、功能截图五、文案资料5.1 选题背景5.2 国内…

高效接口限流:基于自定义注解与RateLimiter的实践

在高并发场景下&#xff0c;接口的流量控制是保证系统稳定性和提升性能的关键之一。通过实现接口限流&#xff0c;我们可以有效避免系统在访问高峰时发生崩溃。本文将详细介绍如何通过自定义注解和切面编程结合RateLimiter来实现接口的限流功能&#xff0c;以应对高并发请求。 …

nodejs:express + js-mdict 网页查询英汉词典,能播放声音

向 DeepSeek R1 提问&#xff1a; 我想写一个Web 前端网页&#xff0c;后台用 nodejs js-mdict, 实现在线查询英语单词 1. 项目结构 首先&#xff0c;创建一个项目目录&#xff0c;结构如下&#xff1a; mydict-app/ ├── public/ │ ├── index.html │ ├── st…

无人机PX4飞控 | PX4源码添加自定义uORB消息并保存到日志

PX4源码添加自定义uORB消息并保存到日志 0 前言 PX4的内部通信机制主要依赖于uORB&#xff08;Micro Object Request Broker&#xff09;&#xff0c;这是一种跨进程的通信机制&#xff0c;一种轻量级的中间件&#xff0c;用于在PX4飞控系统的各个模块之间进行高效的数据交换…

【IocDI】_存储Bean的五大类注解及getBean的使用

目录 1. Bean的存储 1.1 类注解 1.1.1 Controller&#xff1a;控制器存储 1.1.2 Service&#xff1a;服务存储 1.1.3 Repository&#xff1a;仓库存储 1.1.4 Component&#xff1a;组件存储 1.1.5 Configuration&#xff1a;配置存储 1.2 五大类注解之间的关系 2. get…

VLAN 基础 | 不同 VLAN 间通信实验

注&#xff1a;本文为 “ Vlan 间通信” 相关文章合辑。 英文引文&#xff0c;机翻未校。 图片清晰度限于原文图源状态。 未整理去重。 How to Establish Communications between VLANs? 如何在 VLAN 之间建立通信&#xff1f; Posted on November 20, 2015 by RouterSwi…

GRE阅读双线阅读 --青山学堂GRE全程班 包括 阅读、数学、写作、填空、背单词

新版GRE考试整体结构 section题量时间写作1篇issue30min语文S112道题(7道填空5道阅读)18min数学S112道题21min语文S215道题(7道填空8道阅读)23min数学S215道题26min Tips: 写作结束后&#xff0c;语文和数学的顺序不固定&#xff0c;2中可能&#xff1a; issue -> V ->…

5.5.1 面向对象的基本概念

文章目录 基本概念面向对象的5个原则 基本概念 面向对象的方法&#xff0c;特点时其分析与设计无明显界限。虽然在软件开发过程中&#xff0c;用户的需求会经常变化&#xff0c;但客观世界对象间的关系是相对稳定的。对象是基本的运行实体&#xff0c;由数据、操作、对象名组成…

Java_类加载器

小程一言类加载器的基础双亲委派模型核心思想优势 各类加载器的职责 类加载器的工作流程举例&#xff1a;如何在Java中使用类加载器启动类加载器、扩展类加载器与系统类加载器输出解释自定义类加载器 类加载器与类冲突总结 小程一言 本专栏是对Java知识点的总结。在学习Java的过…

开源音乐管理软件Melody

本文软件由网友 heqiusheng 推荐。不过好像已经是一年前了 &#x1f602; 简介 什么是 Melody &#xff1f; Melody 是你的音乐精灵&#xff0c;旨在帮助你更好地管理音乐。目前的主要能力是帮助你将喜欢的歌曲或者音频上传到音乐平台的云盘。 主要功能包括&#xff1a; 歌曲…

一、TensorFlow的建模流程

1. 数据准备与预处理&#xff1a; 加载数据&#xff1a;使用内置数据集或自定义数据。 预处理&#xff1a;归一化、调整维度、数据增强。 划分数据集&#xff1a;训练集、验证集、测试集。 转换为Dataset对象&#xff1a;利用tf.data优化数据流水线。 import tensorflow a…

分析哲学:从 语言解剖到 思想澄清的哲学探险

分析哲学&#xff1a;从 语言解剖 到 思想澄清 的哲学探险 第一节&#xff1a;分析哲学的基本概念与公式解释 【通俗讲解&#xff0c;打比方来讲解&#xff01;】 分析哲学&#xff0c;就像一位 “语言侦探”&#xff0c;专注于 “解剖语言”&#xff0c;揭示我们日常使用的语…

鸿蒙物流项目之基础结构

目录&#xff1a; 1、项目结构2、三种包的区别和使用场景3、静态资源的导入4、颜色样式设置5、修改项目名称和图标6、静态包基础目录7、组件的抽离8、在功能模块包里面引用静态资源包的组件 1、项目结构 2、三种包的区别和使用场景 3、静态资源的导入 放在har包中&#xff0c;那…