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编程中三条常用的技巧
May 11 Python
django中的HTML控件及参数传递方法
Mar 20 Python
对python中raw_input()和input()的用法详解
Apr 22 Python
python 3.7.0 安装配置方法图文教程
Aug 27 Python
Python 一句话生成字母表的方法
Jan 02 Python
Python编程中类与类的关系详解
Aug 08 Python
python GUI编程(Tkinter) 创建子窗口及在窗口上用图片绘图实例
Mar 04 Python
基于SpringBoot构造器注入循环依赖及解决方式
Apr 26 Python
通过自学python能找到工作吗
Jun 21 Python
拿来就用!Python批量合并PDF的示例代码
Aug 10 Python
Python‘==‘ 及 ‘is‘相关原理解析
Sep 05 Python
python字符串的多行输出的实例详解
Jun 08 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
咖啡豆的最常见发酵处理方法,详细了解一下
2021/03/03 冲泡冲煮
PHP 5.3.1 安装包 VC9 VC6不同版本的区别是什么
2010/07/04 PHP
第4章 数据处理-php字符串的处理-郑阿奇(续)
2011/07/04 PHP
基于PHP CURL获取邮箱地址的详解
2013/06/03 PHP
使用PHP求两个文件的相对路径
2013/06/20 PHP
php的webservice的wsdl的XML无法显示问题的解决方法
2014/03/11 PHP
PHP curl实现抓取302跳转后页面的示例
2014/07/04 PHP
php计算两个整数的最大公约数常用算法小结
2015/03/05 PHP
Yii中srbac权限扩展模块工作原理与用法分析
2016/07/14 PHP
PHP Filter过滤器全面解析
2016/08/09 PHP
js Flash插入函数免激活代码
2009/03/31 Javascript
Jqyery中同等与js中windows.onload的应用
2011/05/10 Javascript
jquery获取div距离窗口和父级dv的距离示例
2013/10/10 Javascript
Jquery实现控件的隐藏和显示实例
2014/02/08 Javascript
ExtJs动态生成treepanel的Json格式
2015/07/19 Javascript
原生JS实现美图瀑布流布局赏析
2015/09/07 Javascript
基于JavaScript实现Tab选项卡切换效果
2016/11/24 Javascript
Node.js发送HTTP客户端请求并显示响应结果的方法示例
2017/04/12 Javascript
理解Angular的providers给Http添加默认headers
2017/07/04 Javascript
仿vue-cli搭建属于自己的脚手架的方法步骤
2019/04/17 Javascript
关于Vue源码vm.$watch()内部原理详解
2019/04/26 Javascript
小程序开发之模态框组件封装
2020/04/23 Javascript
[44:15]DOTA2上海特级锦标赛主赛事日 - 5 败者组决赛Liquid VS EG第二局
2016/03/06 DOTA
对numpy中数组转置的求解以及向量内积计算方法
2018/10/31 Python
Python 实现简单的客户端认证
2020/07/29 Python
美国鲍勃商店:Bob’s Stores
2018/07/22 全球购物
J2EE相关知识面试题
2013/08/26 面试题
高二地理教学反思
2014/01/24 职场文书
2014年三八妇女节活动方案
2014/02/28 职场文书
捐书倡议书
2014/08/29 职场文书
2015年乡镇财政工作总结
2015/05/19 职场文书
2015双创工作总结
2015/07/24 职场文书
消防宣传标语大全
2015/08/03 职场文书
基于Nginx实现限制某IP短时间访问次数
2021/03/31 Servers
python通过函数名调用函数的几种方法总结
2021/06/07 Python
winserver2019安装软件一直卡在应用程序正在为首次使用做准备
2022/06/10 Servers