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实现在sqlite动态创建表的方法
May 08 Python
基于Python实现一个简单的银行转账操作
Mar 06 Python
使用Python进行QQ批量登录的实例代码
Jun 11 Python
python numpy 部分排序 寻找最大的前几个数的方法
Jun 27 Python
Django渲染Markdown文章目录的方法示例
Jan 02 Python
Python使用到第三方库PyMuPDF图片与pdf相互转换
May 03 Python
Python 把序列转换为元组的函数tuple方法
Jun 27 Python
python 使用装饰器并记录log的示例代码
Jul 12 Python
解决Python3 控制台输出InsecureRequestWarning问题
Jul 15 Python
python列表推导式操作解析
Nov 26 Python
Python matplotlib画曲线例题解析
Feb 07 Python
利用Python批量识别电子账单数据的方法
Feb 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
PHP面向对象继承用法详解(优化与减少代码重复)
2016/12/02 PHP
解决微信授权回调页面域名只能设置一个的问题
2016/12/11 PHP
AeroWindow 基于JQuery的弹出窗口插件
2011/06/27 Javascript
EXTJS记事本 当CompositeField遇上RowEditor
2011/07/31 Javascript
js function定义函数的几种不错方法
2014/02/27 Javascript
js实现的标题栏新消息闪烁提示效果
2014/06/06 Javascript
基于jQuery实现复选框的全选 全不选 反选功能
2014/11/24 Javascript
jQuery绑定事件的几种实现方式
2016/05/09 Javascript
js canvas实现擦除动画
2016/07/16 Javascript
vue.js入门(3)——详解组件通信
2016/12/02 Javascript
Javascript计算二维数组重复值示例代码
2016/12/18 Javascript
vue数字类型过滤器的示例代码
2017/09/07 Javascript
javascript计算渐变颜色的实例
2017/09/22 Javascript
自定义PC微信扫码登录样式写法
2017/12/12 Javascript
JS highcharts实现动态曲线代码示例
2020/10/16 Javascript
python中os操作文件及文件路径实例汇总
2015/01/15 Python
Python cookbook(数据结构与算法)将序列分解为单独变量的方法
2018/02/13 Python
Python实现的拟合二元一次函数功能示例【基于scipy模块】
2018/05/15 Python
Python获取网段内ping通IP的方法
2019/01/31 Python
django的settings中设置中文支持的实现
2019/04/28 Python
Python 生成器,迭代,yield关键字,send()传参给yield语句操作示例
2019/10/12 Python
python GUI库图形界面开发之PyQt5下拉列表框控件QComboBox详细使用方法与实例
2020/02/27 Python
Python异常处理机制结构实例解析
2020/07/23 Python
python如何获得list或numpy数组中最大元素对应的索引
2020/11/16 Python
Fox Racing英国官网:越野摩托车和山地自行车服装
2020/02/26 全球购物
美国饼干礼物和美食甜点购买网站:Cheryl’s
2020/05/28 全球购物
学习群众路线的心得体会
2014/11/05 职场文书
2014年酒店服务员工作总结
2014/12/08 职场文书
关于清明节的演讲稿2015
2015/03/18 职场文书
2015年五四青年节演讲稿
2015/03/18 职场文书
行政人事专员岗位职责
2015/04/07 职场文书
自我检讨书怎么写
2015/05/07 职场文书
大学生读书笔记大全
2015/07/01 职场文书
公司趣味运动会开幕词
2016/03/04 职场文书
Python线程池与GIL全局锁实现抽奖小案例
2022/04/13 Python
MySQL安装失败的原因及解决步骤
2022/06/14 MySQL