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 相关文章推荐
在Apache服务器上同时运行多个Django程序的方法
Jul 22 Python
python 的列表遍历删除实现代码
Apr 12 Python
纯用NumPy实现神经网络的示例代码
Oct 24 Python
python实现多进程代码示例
Oct 31 Python
Python实现的简单线性回归算法实例分析
Dec 26 Python
在Python运行时动态查看进程内部信息的方法
Feb 22 Python
Django Rest framework三种分页方式详解
Jul 26 Python
DJango的创建和使用详解(默认数据库sqlite3)
Nov 18 Python
tensorflow没有output结点,存储成pb文件的例子
Jan 04 Python
Django模板之基本的 for 循环 和 List内容的显示方式
Mar 31 Python
numpy矩阵数值太多不能全部显示的解决
May 14 Python
pandas.DataFrame.drop_duplicates 用法介绍
Jul 06 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分页详细讲解(有实例)
2013/10/30 PHP
PHP CURL获取返回值的方法
2014/05/04 PHP
php实现过滤字符串中的中文和数字实例
2015/07/29 PHP
Windows 下安装 swoole 图文教程(php)
2017/06/05 PHP
如何用js控制css中的float的代码
2007/08/16 Javascript
用jQuery简化JavaScript开发分析
2009/02/19 Javascript
javascript判断用户浏览器插件安装情况的代码
2011/01/01 Javascript
基于jquery的jqDnR拖拽溢出的修改
2011/02/12 Javascript
js对table的td进行相同内容合并示例详解
2013/12/27 Javascript
js动画效果制件让图片组成动画代码分享
2014/01/14 Javascript
JavaScript中获取高度和宽度函数总结
2014/10/08 Javascript
JavaScript设计模式之外观模式介绍
2014/12/28 Javascript
jquery简单图片切换显示效果实现方法
2015/01/14 Javascript
AngularJS 使用$sce控制代码安全检查
2016/01/05 Javascript
使用jQuery中的wrap()函数操作HTML元素的教程
2016/05/24 Javascript
老生常谈JavaScript数组的用法
2016/06/10 Javascript
Angular ng-repeat遍历渲染完页面后执行其他操作详细介绍
2016/12/13 Javascript
js实现时间轴自动排列效果
2017/03/09 Javascript
vue图片加载与显示默认图片实例代码
2017/03/16 Javascript
详解React 在服务端渲染的实现
2017/11/16 Javascript
基于vue-cli、elementUI的Vue超简单入门小例子(推荐)
2019/04/17 Javascript
JS实现返回上一页并刷新页面的方法分析
2019/07/16 Javascript
vue props 单项数据流实例分享
2020/02/16 Javascript
vue中实现动态生成二维码的方法
2020/02/21 Javascript
React中使用Vditor自定义图片详解
2020/12/25 Javascript
[59:15]完美世界DOTA2联赛PWL S2 LBZS vs FTD.C 第一场 11.20
2020/11/20 DOTA
[46:59]完美世界DOTA2联赛PWL S2 GXR vs Ink 第二场 11.19
2020/11/20 DOTA
python模拟鼠标拖动操作的方法
2015/03/11 Python
Python操作Word批量生成文章的方法
2015/07/28 Python
Python while 循环使用的简单实例
2016/06/08 Python
详解python中的json的基本使用方法
2016/12/21 Python
python反编译学习之字节码详解
2019/05/19 Python
Python面向对象编程基础实例分析
2020/01/17 Python
THE OUTNET美国官网:国际设计师品牌折扣网站
2017/03/07 全球购物
小学教师的个人自我鉴定
2013/10/26 职场文书
建筑管理专业求职信
2014/07/28 职场文书