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 相关文章推荐
Python3访问并下载网页内容的方法
Jul 28 Python
Python算法应用实战之栈详解
Feb 04 Python
Pycharm学习教程(1) 定制外观
May 02 Python
python字符串的方法与操作大全
Jan 30 Python
Python常见字典内建函数用法示例
May 14 Python
python交互模式下输入换行/输入多行命令的方法
Jul 02 Python
pytorch 在网络中添加可训练参数,修改预训练权重文件的方法
Aug 17 Python
Python多线程获取返回值代码实例
Feb 17 Python
python matplotlib imshow热图坐标替换/映射实例
Mar 14 Python
Python文件读写w+和r+区别解析
Mar 26 Python
python 轮询执行某函数的2种方式
May 03 Python
pytorch VGG11识别cifar10数据集(训练+预测单张输入图片操作)
Jun 24 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扩展vld查看PHP opcode操作步骤
2013/03/04 PHP
ThinkPHP访问不存在的模块跳转到404页面的方法
2014/06/19 PHP
取得单条网站评论以数组形式进行输出
2014/07/28 PHP
php中文验证码实现方法
2015/06/18 PHP
实例介绍PHP中zip_open()函数用法
2019/02/15 PHP
jquery制作弹窗提示窗口代码分享
2014/03/02 Javascript
Node.js中require的工作原理浅析
2014/06/24 Javascript
一个字符串反转函数可实现字符串倒序
2014/09/15 Javascript
jquery+CSS3实现淘宝移动网页菜单效果
2015/08/31 Javascript
jQuery焦点图轮播特效代码分享(3款)
2015/09/05 Javascript
基于js里调用函数时,函数名带括号和不带括号的区别
2016/07/28 Javascript
ion content 滚动到底部会遮住一部分视图的快速解决方法
2016/09/06 Javascript
js实现砖头在页面拖拉效果
2020/11/20 Javascript
jquery获取下拉框中的循环值
2017/02/08 Javascript
JavaScript设计模式之工厂模式简单实例教程
2018/07/03 Javascript
解决vue-cli脚手架打包后vendor文件过大的问题
2018/09/27 Javascript
vue中组件的3种使用方式详解
2019/03/23 Javascript
基于Vue 撸一个指令实现拖拽功能
2019/10/09 Javascript
python 图片验证码代码
2008/12/07 Python
python 合并文件的具体实例
2013/08/08 Python
Python中的一些陷阱与技巧小结
2015/07/10 Python
编写Python小程序来统计测试脚本的关键字
2016/03/12 Python
django实现后台显示媒体文件
2020/04/07 Python
keras 读取多标签图像数据方式
2020/06/12 Python
Python使用Selenium实现淘宝抢单的流程分析
2020/06/23 Python
Python 代码调试技巧示例代码
2020/08/11 Python
python中Pexpect的工作流程实例讲解
2021/03/02 Python
好的自荐信的要求
2013/10/30 职场文书
教师实习自我鉴定
2013/12/13 职场文书
个人实习生的自我评价
2014/02/16 职场文书
合伙协议书范本
2014/04/21 职场文书
个人对照检查材料思想汇报
2014/09/26 职场文书
2015年学校保卫部工作总结
2015/05/11 职场文书
初婚初育证明范本
2015/06/18 职场文书
2016新教师岗前培训心得体会
2016/01/08 职场文书
如何用JavaScript实现一个数组惰性求值库
2021/05/05 Javascript