numpy的并行多进程处理

量化工具Numpy知识1:并行化思想与基础操作 Numpy是Python很多科学计算与工程库的基础库,在量化数据分析中最常使用的pandas也是基于Numpy的封装,可以说Numpy就是量化数据分析领域中的基础数组,学会Numpy是量化分析中关键的一步。 Numpy的输出是一个非常大且连续的并由同类型数据组成的内存区域,所以可以构造一个比普通列表大得多的数组,并且灵活高效地对数组中所有的元素进行并行化操作。 一、并行化思想 示例1:... 阅读详情

因为要处理接近32G+数据集,为提高处理效率,没有使用数据库,直接在大内存的机器上用了numpy。

对数据集还要做一些计算,包含逻辑工作流,不能简单向量化。又想进一步提高处理速度,就需要并行化。

关于numpy的ndarray的并行化处理,已经又前人研究过,使用multiprocessing.shared_memory 模块。比较优秀的有:Python多进程处理(读、写)numpy矩阵

这里作一些补充。

1、在Windows系统中(win10 64位),RawArray进入子进程后,会出现“mmap.mmap(-1,...)  ... OSError: [WinError 1450] 系统资源不足,无法完成请求的服务”的错误,也有可能是“ OSError: [WinError 1455] 页面文件太小,无法完成操作”的错误。

虽然在任务管理器中,明显看到实际分配的RawArray还远小于实际内存的容量,但是还是报错。这个问题在linux中不会发生。

解决办法是设置Windows的虚拟内存为固定值,固定值只管放大到比实际内存大,甚至可以到2倍,而且不必放到SSD中,放到机械硬盘里都行。程序实际运行中,可以看到硬盘是不工作的。

在程序运行结束时,还要注意主动 del RawArray,回收一下内存。否则下一次运行时,Windows还可能会报“[WinError 1455] 页面文件太小”的错误。

2、numpy的向量化加速问题。Anaconda Python的numpy是按intel MKL配置加速的,理论上是有向量加速的。但是经过测试,多进程并行处理,还是比单进程要快,所以可以认为intel MKL的向量加速只是基于单核的,如有必要,还是可以把单个numpy.ndarray进行分块,进行并行处理提速。

3、共享的RawArray的并行处理,还是建议使用multiprocessing.Processing,而不要用multiprocessing.Pool。因为前者的父子进程具有继承性,参数传递上无需global化,比较方便。

附上演示代码

# -*- coding: utf-8 -*-
from __future__ import absolute_import, print_function

import multiprocessing
import os, sys, time, gc, psutil
import time
import numpy
import multiprocessing.managers
import multiprocessing.sharedctypes

def multi_run (func, imapS, *args):
    # 类似 pool,但是可以形成 子进程 的继承关系,方便传递 共享内存变量
    print ("len(imapS) ", len(imapS))
    ProcS = []
    for s in imapS:
        p = multiprocessing.Process(target=func,args=(s, *args))
        p.daemon = True
        p.start()
        print ("start .. ", psutil.virtual_memory().used)
        ProcS.append (p)
    
    for p in ProcS:
        p.join()

def Split_List (mList, mSplit):
    # 把一个大 list 基本平均切分成 多份,用于后续的 mulitprocessing 处理
    mp_Length = len(mList)
    step = mp_Length / mSplit # 每份的长度
    if step < 1:
        step = 1
    elif step != int(step):
        step = int(step) + 1
        # 取整后再加1的目的是,不要把前面n个进程余下来的任务,都压倒最后一个进程上
        # 相反,是取最后一个进程工作量不足的,分担到前面的进程中去
    ret = []
    c = 0
    while c < mp_Length :
        ret.append (mList[c: c + step])
        c += step
    return ret

def write_m (mrange, gm, gmp_Count, gstatic_C, static_LL):
    m = numpy.frombuffer(gm, dtype=numpy.uint8)
    m = numpy.reshape (m, (gmp_Count*gstatic_C , static_LL))
    for i in mrange:
        m[i,:] = i+1

def calc_m (mrange, gm, gmp_Count, gstatic_C, static_LL):
    m = numpy.frombuffer(gm, dtype=numpy.uint8)
    m = numpy.reshape (m, (gmp_Count*gstatic_C , static_LL))
    m[mrange,:] = numpy.exp (m[mrange,:])

if __name__ == "__main__":
    multiprocessing.freeze_support()
    mp_Count = multiprocessing.cpu_count()
    # 以下两个参数可根据运行的机器的实际内存容量进行调整,目前参数值适合于32G内存机器
    static_C = 2
    static_LL = 1024 *1024* 512

    raw_arr_m = multiprocessing.sharedctypes.RawArray( \
        numpy.ctypeslib.as_ctypes_type(numpy.uint8), \
        mp_Count*static_C *static_LL)
    m = numpy.frombuffer(raw_arr_m, dtype=numpy.uint8)
    m = numpy.reshape (m, (mp_Count*static_C , static_LL))
    print ("Get Memory .. ", m.shape, psutil.virtual_memory().used)

    for i in range(mp_Count):
        print (i*static_C, m[i*static_C, :10])

    sp = Split_List(list(range(mp_Count*static_C)), mp_Count)
    multi_run (write_m, sp, raw_arr_m, mp_Count, static_C, static_LL)

    print ("calc Start .")
    t0 = time.time()
    m = numpy.exp (m)
    print ("single", time.time() - t0)

    sp = Split_List(list(range(mp_Count*static_C)), mp_Count)
    multi_run (write_m, sp, raw_arr_m, mp_Count, static_C, static_LL)
    t0 = time.time()
    multi_run (calc_m, sp, raw_arr_m, mp_Count, static_C, static_LL)
    print ("multi", time.time() - t0)

    for i in range(m.shape[0]):
        print (i, m[i, :10])
    del raw_arr_m
    gc.collect()

如果处理过程比较简单,使用的 numpy函数能被 numba 模块,则用 numba 更为简便,无需操作 共享内存,即能实现numpy 的并行化计算。比起 numpy.vectorize ,或则 numpy.fromfunction 更为便利。当然 numba 还是有不少限制,有些函数虽然支持,但是参数限制性比原生的 numpy 要范围小得多,前面的办法相对“万能”使用。

对于参数限制了的numpy函数,也可以自行进行算法展开进行弥补。由于 numba 是实时“编译”后执行,在代码量较大的情况下,特别是使用了njit(parallel=True)参数后,即nopython方式,速度还是传统较快得多。在另一个复杂的算例(代码不便贴出),可以比 共享内存的并行方式快上一倍。

 numba 的示例代码如下

# -*- coding: utf-8 -*-
from __future__ import absolute_import, print_function

import multiprocessing
import os, sys, time, gc, psutil
import time
import numpy
import numba
from numba.typed import List

@numba.njit
def write_m (mrange, m):
    for i in mrange:
        m[i,:] = i+1

@numba.njit
def calc_m (mrange, m):
    for i in mrange:
        m[i,:] = numpy.exp (m[i,:]).astype(numpy.uint8)

if __name__ == "__main__":
    multiprocessing.freeze_support()
    mp_Count = multiprocessing.cpu_count()
    # 以下两个参数可根据运行的机器的实际内存容量进行调整,目前参数值适合于32G内存机器
    static_C = 2
    static_LL = 1024 *1024* 512

    m = numpy.empty((mp_Count*static_C , static_LL), dtype=numpy.uint8)
    print ("Get Memory .. ", m.shape, psutil.virtual_memory().used)

    for i in range(mp_Count):
        print (i*static_C, m[i*static_C, :10])

    write_m (List(range(mp_Count*static_C)), m)

    print ("calc Start .")

    t0 = time.time()
    m = numpy.exp (m).astype(numpy.uint8)
    print ("single", time.time() - t0)

    write_m (List(range(mp_Count*static_C)), m)

    t0 = time.time()
    calc_m (List(range(mp_Count*static_C)), m)
    print ("multi", time.time() - t0)

    for i in range(m.shape[0]):
        print (i, m[i, :10])

图解 NumPy 学习笔记(一):初识 NumPy import numpy as np # 导入 NumPy, 开始学习 感谢 NumPy, 本系列将使用图解以及脑图的方法来记录我的《图解 NumPy 学习笔记》。 NumPy是 Numerical Python 的简称,它是目前 Python 数值计算中最为重要的基础包。大多数计算包都提供了基于 NumPy 的科学计算函数功能,将 NumPy 的数组对象作为数据交换的通用语。—... 阅读详情

相关推荐

【Numpy核心编程攻略:Python数据处理、分析详解与科学计算】4.5 NumPy中的并行计算

通过本文的介绍,我们了解了并行计算的基本概念,以及如何使用 NumPy 和相关库(如threadingjoblibdask和numba)进行并行计算。并行计算在处理大规模数据时能够显著提高计算效率,是现代数据科学中不可或缺的技术。更高效的并行算法:随着硬件技术的发展,新的并行算法不断涌现,可以进一步优化并行计算的性能。跨平台并行计算:探索如何在不同平台(如 GPU、TPU)上进行并行计算,以适应不同的计算需求。自动并行化:开发工具和框架,自动将 Python 代码并行化,减少手动优化的工作量。

1102

NumPy 使用笔记

NumPy是Python中用于科学计算的核心库,提供了强大的矩阵操作功能。文章介绍了NumPy的基本使用:1) 数组初始化,可通过列表、arange函数或读取文件数据;2) 矩阵运算包括形状变换、点乘/矩阵乘法(使用dot/@运算符)、求逆/伪逆、转置及元素级加减乘除;3) 统计函数如min/max/mean;4) 多项式曲线拟合;5) 数据存储与读取,支持.npy/.npz格式;6) 矩阵扩展方法如tile复制和vstack/hstack组合。NumPy的矩阵操作与MATLAB类似,是Python科学计算

人无远虑,必有近忧 938

NumPy 高级教程——并行计算

通过结合上述技巧,你可以在 NumPy 中实现并行计算,提高代码的执行效率。选择合适的工具和技术取决于你的具体应用场景和计算任务。希望本篇博客能够帮助你更好地理解和运用 NumPy 中的并行计算技术。

Echo_Wish 1679

利用 NumPy 进行并行计算的 10 个优化建议

本文介绍了利用 NumPy 进行并行计算的十个优化建议,包括使用内置函数、合理使用内存视图、向量化操作、广播机制、多线程、Numba 加速、Cython 加速、Dask 分布式计算、GPU 加速以及多进程并行计算。通过这些方法,你可以在处理大规模数据集时显著提升 NumPy 的性能。希望这些建议对你有所帮助。

2401_85903292的博客 2600

【Python图像处理】30 图像处理性能优化与并行计算

图像处理通常是计算密集型任务,特别是处理高分辨率图像或视频时,计算量非常大。性能瓶颈可能出现在以下几个方面:CPU计算能力、内存带宽、磁盘I/O、算法复杂度等。理解性能瓶颈的位置是进行有效优化的前提。CPU计算能力是图像处理的主要瓶颈之一。图像处理涉及大量的算术运算,如卷积、滤波、变换等,这些运算需要消耗大量的CPU周期。对于复杂的算法,单线程执行可能无法满足实时性要求。内存带宽是另一个重要的性能瓶颈。图像数据量大,频繁的内存访问会消耗大量时间。

nmdbbzcl的博客 75

并行处理与遗传算法在Python中的实现

本文介绍如何在Python中使用numpy数组和DEAP库处理遗传算法的并行计算。重点在于评估函数的性能和并行处理的优势与局限性,并通过旅行商问题(TSP)示例来说明如何在多处理器环境下实现算法。

weixin_29009401的博客 483

高效处理大规模数据:使用 Python 进行内存优化和并行计算

高效处理大规模数据不仅仅依赖于强大的硬件资源,还需要通过合理的编程技巧和技术来优化内存使用和加速计算。通过利用 Python 的内存优化技术、生成器、NumPy/Pandas 的高效数据结构,以及多线程、多进程和异步编程等并行计算方法,开发者能够在处理大数据时获得显著的性能提升。这些技术可以帮助你在开发中更好地应对大规模数据处理的挑战,无论是在数据分析、机器学习模型训练,还是在日常的业务数据处理任务中,都能提供巨大的帮助。

这里只有干货:从 Modbus 通信到 MES 对接,从 YOLO 训练到工控机部署,带你搞定工业软件开发全流程。 1363

并行编程架构与模型的深入介绍

并行编程是指通过构建能够同时执行多个计算任务的程序,来充分利用多处理器或多核处理器的计算能力。与传统的串行编程不同,在并行编程中,任务不是按顺序执行,而是可以同时执行或被分配到不同的处理单元上。

weixin_29859471的博客 1079

python 导入numpy 导致多进程绑定同一个CPU问题解决方法

python 如果有导入numpy模块的import语句,会导致默认将多进程程序的每个进程都绑定到同一个CPU core上, 失去了多进程在多核CPU上的性能优越性,这和CPU affinity(CPU亲和性)有关,解决办法: 导入affinity包,执行: affinity.set_process_affinity_mask(0,2**multiprocessing.cpu_count()...

weixin_33889665的博客 164

LD14激光雷达与STM32F103C8T6(标准库)获取雷达360度数据(1)

LD14激光雷达与STM32F103C8T6(标准库)获取雷达360度数据(1)

qq_54206194的博客 3899

分布式光纤传感(DFOS)DTS/DAS/DSS 三合一:10公里管线监测实战与数据解读

本文详细介绍了分布式光纤传感(DFOS)技术在10公里管线监测中的实战应用,通过DTS(温度)、DAS(振动)、DSS(应变)三合一系统,实现对管线健康状态的立体感知。文章涵盖工程部署、数据采集、多物理量数据融合及噪声抑制等关键技术,展示了如何通过一根光纤完成复杂监测任务,显著提升管线安全性和维护效率。

weixin_29168153的博客 315

Python多进程处理(读、写)numpy矩阵

前言 由于需要使用python处理一个380*380的numpy矩阵,经过计算后对其中的每个元素进行赋值,单进程处理大约需要4小时,要处理几百个矩阵,时间上有些耗不起,研究了一下python的多进程(multiprocessing),坑点在于numpy array需要在多个子进程之间共享,总结如下。不对或不妥之处望轻喷。 另,据说python目前已加入multiprocessing.shared_memory模块,由于使用的某些包不支持python3.8及以上版本,所以未作研究。目前代码基于Pytho.

Hayreen的博客 6283

SpringBoot+VUE3实战:如何用WebSocket搞定网页端语音通话(避坑指南)

本文详细介绍了如何使用SpringBoot和VUE3结合WebSocket技术实现网页端语音通话功能。从环境配置、WebSocket服务端实现到前端音频处理,提供了完整的开发指南和避坑建议,帮助开发者快速构建稳定高效的实时语音通信系统。

weixin_29021195的博客 221

Python在科学计算中的并行处理

其次,要留意数据序列化的问题,进程之间传递数据是需要序列化和反序列化的,如果数据本身特别大,这个开销也得考虑进去。从简单的 到方便的 ,再到专业的 ,Python提供的工具链足以应对从桌面到集群的各种场景。当然,科学计算领域绕不开的 和 ,它们本身在一些底层线性代数运算上就利用了BLAS/LAPACK这些库,这些库本身往往是多线程的。Python这语言,好用是真好吃,生态丰富,写起来也顺手。它在背后也是用的多进程,而且对循环并行化的支持非常好,在很多机器学习库的数据预处理环节都能看到它的身影。

2509_93942407的博客 394

QMI8658A和QMC5883L传感器校准全攻略:从零偏校准到椭球拟合

本文详细解析了QMI8658A和QMC5883L传感器的校准方法,从零偏校准到椭球拟合,涵盖了9轴运动传感器的核心误差来源及补偿技术。通过实战案例和数学建模,帮助开发者提升传感器精度,适用于无人机、AR/VR等智能硬件应用。

weixin_29189381的博客 158

拉曼光谱入门:10.显微拉曼与共聚焦技术

本文系统阐述了显微拉曼光谱技术与共聚焦原理的融合机制,详细解析了从激光激发、针孔空间滤波到光谱采集的完整光路架构,阐明了共聚焦设计在提升三维空间分辨率、抑制荧光背景及实现微区无损层析方面的核心优势,并探讨了关键光学器件的性能边界与系统技术局限。

qq_53529450的博客 167

Python实现高效数据处理的五个技巧

例如,使用NumPy的ndarray进行数值计算时,其底层C实现相比纯Python循环可提速数十倍。对于可并行的数据预处理任务,如同时处理多个文件或独立的数据分块,使用ProcessPoolExecutor可以充分利用多核CPU资源。例如,在处理时间序列数据分析时,对关键循环使用cdef定义变量类型,可达到接近纯C语言的执行效率,同时保留Python的易用性特性。通过创建内存映射数组,可以像操作普通数组一样进行切片和计算,操作系统会自动处理磁盘与内存之间的数据交换,实现高效的内存管理。

zw2111983的专栏 280

C# Modbus通信从入门到精通(2)——Modbus RTU协议原理

本文详细的介绍了Modbus RTU协议的原理,由多年经验高级工程师实战总结而成,绝对干货!

qq_34059233的博客 6384

Python中实现高效数据处理的5个实用技巧

在Python中,Pandas库提供了强大的向量化操作功能,能够显著提升数据处理效率。与传统的循环操作相比,向量化操作利用底层优化的C语言实现,减少了Python解释器的开销。Dask是一个用于并行计算的灵活库,特别适合处理超出内存容量的大型数据集。这些技巧结合使用,能够显著提升Python数据处理的效率和性能,特别是在处理大规模数据集时效果更为明显。1. 内存管理:定期使用`del`删除不再需要的大对象,调用`gc.collect()`进行垃圾回收。### 1. 使用Pandas的向量化操作替代循环。

jLQlFNWM的博客 285

yolov11添加P2小目标检测头与添加P6超大目标检测头

本文介绍了YOLO目标检测模型中上下采样的原理及应用。上采样通过插值算法放大特征图,YOLO通常采用最近邻插值;下采样则通过带步长的卷积缩小特征图提取高层语义特征。文章详细阐述了这两种操作在YOLO中的实现方式、结构特点及对称性问题,指出下采样后会使用C3模块进行特征整合,上采样后通过concat抑制分割感。此外,还分析了不同分辨率特征图适合检测不同尺寸目标的原因,并提出添加4倍小目标检测头的方法,即对上采样后的特征进行concat和C3模块处理。最后给出了YOLOv5原模型结构和添加4倍检测头后的结构对比

m0_64661770的博客 821

Android 13.0仿ios的hotseat效果修改hotseat样式

在13.0系统产品rom定制化开发中,在项目需求的需要,系统原生Launcher的布局样式很一般,所以需要重新设计ui对布局样式做调整,产品在看到 ios的hotseat效果觉得特别美观,所以要仿ios一样不需要横屏铺满的效果 居中显示就行了,所以就要看hotseat的具体布局显示了

安卓兼职framework和app工程师的博客 1144

Python中高效数据处理的5个实用技巧

df['B'] = df['B'].astype('float32') # 用float32替代float64。df['A'] = df['A'].astype('int8') # 用int8替代int64。这些技巧结合使用,能够显著提升Python数据处理的效率和性能,特别是在处理大规模数据集时效果更为明显。选择合适的数据类型能大幅减少内存使用,特别是在处理大型数据集时。当处理无法一次性加载到内存的大型文件时,分块读取是必备技巧。对于计算密集型任务,使用多进程可以充分利用多核CPU。

sggtaRjB的博客 406

LinePhone3.2.7(android端最新版本) sip客户端

SIP客户端For android:LinePhone3.2.7(最新版本),官网地址:http://www.linphone.org/

上一篇: 卡车运油一题的求解
下一篇: selenium.webdriver 使用中的几点小经验
makefool
博客等级 码龄23年 54粉丝 10原创
评论 2
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值