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解析json实例方法
Nov 19 Python
Python 创建子进程模块subprocess详解
Apr 08 Python
python批量制作雷达图的实现方法
Jul 26 Python
利用Python开发实现简单的记事本
Nov 15 Python
python下os模块强大的重命名方法renames详解
Mar 07 Python
python scipy卷积运算的实现方法
Sep 16 Python
python使用matplotlib绘制雷达图
Oct 18 Python
详解Python中字符串前“b”,“r”,“u”,“f”的作用
Dec 18 Python
dpn网络的pytorch实现方式
Jan 14 Python
Python二元算术运算常用方法解析
Sep 15 Python
python3中确保枚举值代码分析
Dec 02 Python
python引入其他文件夹下的py文件具体方法
May 23 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
实现dedecms全站URL静态化改造的代码
2007/03/29 PHP
php根据日期或时间戳获取星座信息和生肖等信息
2015/10/20 PHP
Yii数据读取与跳转参数传递用法实例分析
2016/07/12 PHP
PHP实现将MySQL重复ID二维数组重组为三维数组的方法
2016/08/01 PHP
js报错 Object doesn't support this property or method的原因分析
2011/03/31 Javascript
js实现弹窗插件功能实例代码分享
2013/12/12 Javascript
使用jQuery.wechat构建微信WEB应用
2014/10/09 Javascript
JS动态修改iframe高度和宽度的方法
2015/04/01 Javascript
javascript多行字符串的简单实现方式
2015/05/04 Javascript
简单介绍jsonp 使用小结
2016/01/27 Javascript
JS转换HTML转义符的方法
2016/08/24 Javascript
JS继承之借用构造函数继承和组合继承
2016/09/07 Javascript
NodeJS仿WebApi路由示例
2017/02/28 NodeJs
Vue的实例、生命周期与Vue脚手架(vue-cli)实例详解
2017/12/27 Javascript
swiper自定义分页器使用方法详解
2020/09/14 Javascript
vue.js整合vux中的上拉加载下拉刷新实例教程
2018/01/09 Javascript
理解Koa2中的async&await的用法
2018/02/05 Javascript
vue 实现 rem 布局或vw 布局的方法
2019/11/13 Javascript
AJAX XMLHttpRequest对象创建使用详解
2020/08/20 Javascript
vue中echarts的用法及与elementui-select的协同绑定操作
2020/11/17 Vue.js
python进阶教程之异常处理
2014/08/30 Python
Python中的集合类型知识讲解
2015/08/19 Python
python机器学习理论与实战(二)决策树
2018/01/19 Python
python list转矩阵的实例讲解
2018/08/04 Python
Python读写zip压缩文件的方法
2018/08/29 Python
python实现银联支付和支付宝支付接入
2019/05/07 Python
python正则表达式匹配不包含某几个字符的字符串方法
2019/07/23 Python
Python3.x+迅雷x 自动下载高分电影的实现方法
2020/01/12 Python
python实现学生管理系统开发
2020/07/24 Python
Html5 webview元素定位工具的实现
2020/08/07 HTML / CSS
董事长秘书职责
2014/01/31 职场文书
好学生评语大全
2014/05/05 职场文书
2015民办小学年度工作总结
2015/05/26 职场文书
大学生如何逃脱“毕业季创业队即散伙”魔咒?
2019/08/19 职场文书
使用Redis实现秒杀功能的简单方法
2021/05/08 Redis
PHP中多字节字符串操作实例详解
2021/08/23 PHP