《Python开发 - Python库》pyarrow安装与使用(矩阵运算库)

本文介绍了Apache Arrow库的Python实现pyarrow,探讨了其与pandas在数据读取效率上的对比,展示了pyarrow在大规模数据处理中的优势。通过实际案例和安装指南,突出了其内存优化和跨平台兼容性的重要性。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

1 pyarrow简介

pyarrow是用于Apache Arrow的Python库。这个库为Arrow c++库提供的功能提供了Python API,以及用于与panda、NumPy和Python生态系统中的其他软件进行箭头集成和互操作性的工具。Apache Arrow是一个用于内存分析的开发平台。它包含一组技术,使大数据系统能够快速处理和移动数据。

Arrow特点
Format: Apache Arrow为平面和层次数据定义了一种与语言无关的柱状内存格式,这种格式的组织用于在现代硬件(如cpu和gpu)上进行高效的分析操作。Arrow内存格式还支持零拷贝读取,用于不需要序列化开销的闪电般的数据访问。

Libraries: Arrow的库实现了这种格式,并为一系列用例提供了构建块,包括高性能分析。许多流行的项目使用箭头有效地发送柱状数据,或者作为分析引擎的基础。库可用于C、c++、c#、Go、Java、JavaScript、MATLAB、Python、R、Ruby和Rust。请参阅如何安装和启动。

Ecosystem:Apache Arrow是由开发人员社区创建并为其服务的软件。我们致力于开放、友好的沟通和协商一致的决策。我们的提交者来自不同的组织和背景,我们欢迎所有人与我们一起参与。

2 pyarrow安装

Pyarrow安装很简单,如果有网络的话,使用以下命令就行:

#pip install pyarrow

Pyarrow比较大,可能使用官方的源导致安装失败,我有两种解决办法:

方法一:更换数据源
可以使用国内的源,比如清华的源,安装命令如下:

#pip install --user -i https://pypi.tuna.tsinghua.edu.cn/simple pyarrow

方法二:离线安装
先到官网或者镜像源下载安装包

pyarrow下载地址

在这里插入图片描述

下载后使用以下命令安装:

#pip install pyarrow-2.0.0-cp38-cp38-win_amd64.whl

3 pyarrow使用

前面讲了pyarrow的简介和安装,接下来我们试试pyarrow到底有没有优势,我们知道,在做数据处理的时候,IO操作将占用大量的时间,提高IO操作效率,也就提升了整体效率,我们就拿大家熟悉的pandas来比较。

代码如下:

import time

from pyarrow import csv

def load_by_arrow(filePath):
    # API :https://arrow.apache.org/docs/python/generated/pyarrow.csv.read_csv.html
    table = csv.read_csv(filePath)
    
    return table.to_pandas()

import pandas as pd
def load_by_pandas(filePath):
    df = pd.read_csv(filePath)
    
    return df
    

if __name__ == "__main__":  
    filePath = 'workdf.csv'
        
    start = time.time()
    pa_df = load_by_arrow(filePath)
    end = time.time()
    print(end-start)
    
    start = time.time()
    pd_df = load_by_pandas(filePath)
    end = time.time()
    print(end-start)

运行结果如下:
在这里插入图片描述

我们可以看到,pyarrow的读取时间是pandas的两倍还多,可想而知,如果处理大批量的数据,效果将更加明显。




欢迎访问我的网站:

BruceOu的哔哩哔哩
BruceOu的主页
BruceOu的博客
BruceOu的CSDN博客
BruceOu的简书

接收更多精彩文章及资源推送,请订阅我的微信公众号:

在这里插入图片描述

<think>嗯,我现在遇到了一个Python中的内存不足问题,具体是在使用apply和lambda函数处理一个形状为(47, 298369)、数据类型为object的大数组时出现的MemoryError。我需要找到解决办法。首先,我应该了解一下为什么会出现这个问题。可能的原因有很多,比如数据量太大,超出了可用内存;或者apply和lambda的使用方式不够高效,导致内存占用过高。 根据用户提供的引用,比如引用[1]提到了Python的内存管理机制和gc模块,这可能和内存回收有关。或许在使用apply和lambda时,中间变量没有被及时释放,导致内存累积。另外,引用[3]提到pop方法可能导致内存状态不一致,但这里的情况不太一样,不过可能需要注意某些操作是否会导致内存泄漏。 接下来,我需要考虑解决方案。可能的思路包括优化数据结构、减少内存占用、使用更高效的处理方法、分块处理数据等。比如,将数据类型从object转换成更节省内存的类型,如float32或int32,这样每个元素占用的内存会更少。同时,使用向量化操作代替apply和lambda,因为Pandas或NumPy的向量化操作通常比逐元素应用函数更高效。 另外,分块处理数据也是一个可行的方法,将大数组分成若干块,逐块处理,避免一次性加载到内存中。使用生成器或迭代器来处理数据,而不是一次性处理整个数组。还可以考虑使用更高效的内存管理工具,如Dask,它支持并行计算和分块处理,适合处理超出内存的数据集。 在引用[2]中提到的numpy.lib.recfunctions.append_fields,可能和结构化数组有关,但不确定是否直接相关。不过,使用NumPy的优化方法可能有帮助,比如避免在循环中不断扩展数组,而是预分配空间。或者,检查是否有不必要的中间变量占用内存,及时删除它们,并使用gc.collect()手动触发垃圾回收。 此外,可能需要检查代码中是否有冗余的数据复制操作。例如,使用apply时,是否会创建多个临时DataFrame或数组,导致内存翻倍。改用原地操作或视图(view)而不是副本(copy)可以减少内存使用。如果数据中有很多重复的值,可以考虑使用更高效的数据结构,如稀疏矩阵。 总结一下,可能的解决方案包括: 1. 转换数据类型以减少内存占用。 2. 使用向量化操作替代apply和lambda。 3. 分块处理数据,逐块处理并保存结果。 4. 优化内存管理,及时释放无用变量,手动垃圾回收。 5. 使用高效的数据处理,如Dask或NumPy。 6. 避免不必要的数据复制,使用视图或原地操作。 接下来需要逐一验证这些方法的可行性。例如,检查当前数组的数据类型,如果确实是object类型,转换成数值类型可能会大幅减少内存。对于形状(47, 298369),总共有约14,023,343个元素,每个object可能占用较多内存,比如每个Python对象引用可能占8字节,这样总内存大约是14M*8=112MB,但实际object的内容可能更大,比如字符串或其他复杂类型,转换成数值类型如float32,每个元素4字节,总内存约56MB,这样内存压力会小很多。 如果数据类型无法转换,可能需要分块处理。例如,将298369列分成多个块,每次处理一部分列,避免同时处理所有列。使用Pandas的chunksize参数或者手动分块处理。 另外,检查是否有其他内存占用高的进程在运行,释放尽可能多的内存资源。或者考虑升级硬件,增加内存,但这可能不是立即可行的解决方案。 最后,确保代码中没有内存泄漏,例如循环中不断追加数据而未释放旧数据。使用内存分析工具如memory_profiler来定位内存使用的高点,进而优化相关代码。</think>在处理形状为$(47, 298369)$、数据类型为`object`的大数组时,使用`apply``lambda`可能导致内存分配失败。以下是分步解决方案: --- ### **1. 数据类型优化** **问题分析**:`object`类型内存效率极低,每个元素存储为Python对象引用(额外元数据占用内存) **解决方案**: - 转换为数值类型(如`float32`): ```python import numpy as np arr = np.array(your_data, dtype=np.float32) # 内存减少至1/4 ``` - 若含字符串,改用分类类型(`category`): ```python import pandas as pd df = df.astype('category') # 适用于重复值较多的场景[^1] ``` --- ### **2. 向量化替代逐行操作** **问题分析**:`apply``lambda`逐行处理效率低,产生中间变量 **解决方案**: - 使用NumPy/Pandas内置函数: ```python # 示例:替代lambda计算平方 result = arr ** 2 # 直接向量化操作,无需apply ``` - 复杂运算可借助`numpy.vectorize`(伪向量化,但效率仍优于`apply`)[^2] --- ### **3. 分块处理策略** **问题分析**:一次性加载全量数据导致内存峰值过高 **解决方案**: - **按列分块处理**: ```python chunk_size = 5000 # 根据内存调整块大小 for i in range(0, arr.shape[1], chunk_size): chunk = arr[:, i:i+chunk_size] process_chunk(chunk) # 替换为实际处理函数 ``` - **使用Dask**(支持懒加载分块计算): ```python import dask.array as da dask_arr = da.from_array(arr, chunks=(47, 10000)) # 定义分块大小 result = dask_arr.map_blocks(your_function).compute() ``` --- ### **4. 内存管理优化** **问题分析**:Python垃圾回收机制未及时释放中间变量 **解决方案**: - 手动触发垃圾回收: ```python import gc del chunk # 删除大对象后立即回收 gc.collect() ``` - 避免深拷贝,使用视图(`view`)或原地操作: ```python arr *= 2 # 原地修改,而非创建新数组 ``` --- ### **5. 替代工具硬件优化** - 换用**PyArrow**处理内存映射文件: ```python import pyarrow as pa table = pa.Table.from_pandas(df) pa.parquet.write_table(table, 'data.parquet') # 支持按需加载部分数据 ``` - 使用SSD硬盘加速分块读写,或升级内存配置。 --- ### **典型代码改造示例** 原始低效代码: ```python df.apply(lambda x: x*2 + 5, axis=1) ``` 优化后代码: ```python df = df.astype(np.float32) result = df * 2 + 5 # 完全向量化 ``` ---
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Bruceoxl

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值