pandas apply多线程实现代码


Posted in Python onAugust 17, 2020

一、多线程化选择

     并行化一个代码有两大选择:multithread 和 multiprocess。

     Multithread,多线程,同一个进程(process)可以开启多个线程执行计算。每个线程代表了一个 CPU 核心,这么多线程可以访问同样的内存地址(所谓共享内存),实现了线程之间的通讯,算是最简单的并行模型。

    Multiprocess,多进程,则相当于同时开启多个 Python 解释器,每个解释器有自己独有的数据,自然不会有数据冲突。

二、并行化思想

并行化的基本思路是把 dataframe 用 np.array_split 方法切割成多个子 dataframe。再调用 Pool.map 函数并行地执行。注意到顺序执行的 pandas.DataFrame.apply 是如何转化成 Pool.map 然后并行执行的。

Pool 对象是一组并行的进程,开源Pool类

开源Pool类定义

def Pool(self, processes=None, initializer=None, initargs=(),
       maxtasksperchild=None):
    '''Returns a process pool object'''
    from .pool import Pool
    return Pool(processes, initializer, initargs, maxtasksperchild,
          context=self.get_context())

设置进程初始化函数

def init_process(global_vars):
  global a
  a = global_vars

设置进程初始化函数

Pool(processes=8,initializer=init_process,initargs=(a,))

其中,指定产生 8 个进程,每个进程的初始化需运行 init_process函数,其参数为一个 singleton tuple a. 利用 init_process 和 initargs,我们可以方便的设定需要在进程间共享的全局变量(这里是 a)。

with 关键词是 context manager,避免写很繁琐的处理开关进程的逻辑。

with Pool(processes=8,initializer=init_process,initargs=(a,)) as pool:    
    result_parts = pool.map(apply_f,df_parts)

三、多线程化应用

多线程时间比较和多线程的几种apply应用

import numpy as np
import pandas as pd
import time
from multiprocessing import Pool

def f(row):
  #直接对某列进行操作
  return sum(row)+a

def f1_1(row):
  #对某一列进行操作,我这里的columns=range(0,2),此处是对第0列进行操作
  return row[0]**2

def f1_2(row1):
  #对某一列进行操作,我这里的columns=range(0,2),此处是对第0列进行操作
  return row1**2

def f2_1(row):
  #对某两列进行操作,我这里的columns=range(0,2),此处是对第0,2列进行操作
  return pd.Series([row[0]**2,row[1]**2],index=['1_1','1_2'])

def f2_2(row1,row2):
  #对某两列进行操作,我这里的columns=range(0,2),此处是对第0,2列进行操作
  return pd.Series([row1**2,row2**2],index=['2_1','2_2'])

def apply_f(df):
  return df.apply(f,axis=1)

def apply_f1_1(df):
  return df.apply(f1_1,axis=1)

def apply_f1_2(df):
  return df[0].apply(f1_2)

def apply_f2_1(df):
  return df.apply(f2_1,axis=1)

def apply_f2_2(df):
  return df.apply(lambda row :f2_2(row[0],row[1]),axis=1)
 
def init_process(global_vars):
  global a
  a = global_vars
  
def time_compare():
  '''直接调用和多线程调用时间对比'''
  a = 2
  np.random.seed(0)
  df = pd.DataFrame(np.random.rand(10**5,2),columns=range(0,2))
  print(df.columns)
   
  t1= time.time()
  result_serial = df.apply(f,axis=1)
  t2 = time.time()
  print("Serial time =",t2-t1)
  print(result_serial.head())

  
  df_parts=np.array_split(df,20)
  print(len(df_parts),type(df_parts[0]))
  with Pool(processes=8,initializer=init_process,initargs=(a,)) as pool: 
  #with Pool(processes=8) as pool:    
    result_parts = pool.map(apply_f,df_parts)
  result_parallel= pd.concat(result_parts)
  t3 = time.time()
  print("Parallel time =",t3-t2)
  print(result_parallel.head())


def apply_fun():
  '''多种apply函数的调用'''
  a = 2
  np.random.seed(0)
  df = pd.DataFrame(np.random.rand(10**5,2),columns=range(0,2))
  print(df.columns)
  df_parts=np.array_split(df,20)
  print(len(df_parts),type(df_parts[0]))
  with Pool(processes=8,initializer=init_process,initargs=(a,)) as pool: 
  #with Pool(processes=8) as pool:    
    res_part0 = pool.map(apply_f,df_parts)
    res_part1 = pool.map(apply_f1_1,df_parts)
    res_part2 = pool.map(apply_f1_2,df_parts)
    res_part3 = pool.map(apply_f2_1,df_parts)
    res_part4 = pool.map(apply_f2_2,df_parts)

  res_parallel0 = pd.concat(res_part0)
  res_parallel1 = pd.concat(res_part1)
  res_parallel2 = pd.concat(res_part2)
  res_parallel3 = pd.concat(res_part3)
  res_parallel4 = pd.concat(res_part4)
  
  print("f:\n",res_parallel0.head())
  print("f1:\n",res_parallel1.head())
  print("f2:\n",res_parallel2.head())
  print("f3:\n",res_parallel3.head())
  print("f4:\n",res_parallel4.head())

  df=pd.concat([df,res_parallel0],axis=1)
  df=pd.concat([df,res_parallel1],axis=1)
  df=pd.concat([df,res_parallel2],axis=1)
  df=pd.concat([df,res_parallel3],axis=1)
  df=pd.concat([df,res_parallel4],axis=1)

  print(df.head())
      
  
if __name__ == '__main__':
  time_compare()
  apply_fun()

参考网址

https://blog.fangzhou.me/posts/20170702-python-parallelism/

https://docs.python.org/3.7/library/multiprocessing.html

到此这篇关于pandas apply多线程实现代码的文章就介绍到这了,更多相关pandas apply多线程内容请搜索三水点靠木以前的文章或继续浏览下面的相关文章希望大家以后多多支持三水点靠木!

Python 相关文章推荐
python中的列表推导浅析
Apr 26 Python
Python脚本实现网卡流量监控
Feb 14 Python
Python本地与全局命名空间用法实例
Jun 16 Python
python读取TXT到数组及列表去重后按原来顺序排序的方法
Jun 26 Python
python 编程之twisted详解及简单实例
Jan 28 Python
在Pycharm中自动添加时间日期作者等信息的方法
Jan 16 Python
python+numpy按行求一个二维数组的最大值方法
Jul 09 Python
对于Python深浅拷贝的理解
Jul 29 Python
安装2019Pycharm最新版本的教程详解
Oct 22 Python
Django使用消息提示简单的弹出个对话框实例
Nov 15 Python
Python While循环语句实例演示及原理解析
Jan 03 Python
基于 Python 实践感知器分类算法
Jan 07 Python
简述python Scrapy框架
Aug 17 #Python
python使用多线程查询数据库的实现示例
Aug 17 #Python
python使用建议与技巧分享(一)
Aug 17 #Python
Python2.6版本pip安装步骤解析
Aug 17 #Python
python中pathlib模块的基本用法与总结
Aug 17 #Python
Pycharm无法打开双击没反应的问题及解决方案
Aug 17 #Python
详解python datetime模块
Aug 17 #Python
You might like
在线竞拍系统的PHP实现框架(一)
2006/10/09 PHP
PHP调用三种数据库的方法(1)
2006/10/09 PHP
PHP5各个版本的新功能和新特性总结
2014/03/16 PHP
PHP生成指定随机字符串的简单实现方法
2015/04/01 PHP
php中通过eval实现字符串格式的计算公式
2017/03/18 PHP
PHP设计模式之适配器模式原理与用法分析
2018/04/25 PHP
jscript之Read an Excel Spreadsheet
2007/06/13 Javascript
判断浏览器的javascript版本的代码
2010/09/03 Javascript
有关JavaScript的10个怪癖和秘密分享
2011/08/28 Javascript
js实现字符串的16进制编码不加密
2014/04/25 Javascript
javascript中$(function() {});写与不写有哪些区别
2015/08/10 Javascript
js document.getElementsByClassName的使用介绍与自定义函数
2016/11/25 Javascript
使用Bootstrap Tabs选项卡Ajax加载数据实现
2016/12/23 Javascript
jQuery Validate插件自定义验证规则的方法
2016/12/27 Javascript
JavaScript中从setTimeout与setInterval到AJAX异步
2017/02/13 Javascript
nodejs中express入门和基础知识点学习
2018/09/13 NodeJs
vuex实现及简略解析(小结)
2019/03/01 Javascript
Vue商品控件与购物车联动效果的实例代码
2019/07/21 Javascript
js将URL网址转为16进制加密与解密函数
2020/03/04 Javascript
[51:50]完美世界DOTA2联赛 Magma vs GXR 第一场 11.07
2020/11/10 DOTA
解决python3在anaconda下安装caffe失败的问题
2017/06/15 Python
对python模块中多个类的用法详解
2019/01/10 Python
Python为何不能用可变对象作为默认参数的值
2019/07/01 Python
python join方法使用详解
2019/07/30 Python
Python实现RabbitMQ6种消息模型的示例代码
2020/03/30 Python
python 基于opencv实现高斯平滑
2020/12/18 Python
澳大利亚百货商店中销量第一的商务衬衫品牌:Van Heusen
2018/07/26 全球购物
毕业生自我鉴定
2013/11/05 职场文书
创业计划实施的7大步骤
2014/02/05 职场文书
《一株紫丁香》教学反思
2014/02/19 职场文书
开展创先争优活动总结
2014/08/28 职场文书
2014年综治维稳工作总结
2014/11/17 职场文书
小学生交通安全寄语
2015/02/27 职场文书
学校计划生育责任书
2015/05/09 职场文书
优秀学生主要事迹怎么写
2015/11/04 职场文书
《总之就是很可爱》新作短篇动画《总之就是很可爱~制服~》将于2022年夏天播出
2022/04/07 日漫