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中逗号的三种作用实例分析
Jun 08 Python
编写Python小程序来统计测试脚本的关键字
Mar 12 Python
Python操作mysql数据库实现增删查改功能的方法
Jan 15 Python
python实现淘宝秒杀聚划算抢购自动提醒源码
Jun 23 Python
Python3实现的爬虫爬取数据并存入mysql数据库操作示例
Jun 06 Python
python实现多层感知器
Jan 18 Python
Python3按一定数据位数格式处理bin文件的方法
Jan 24 Python
python字典改变value值方法总结
Jun 21 Python
python解析多层json操作示例
Dec 30 Python
Python基于百度AI实现OCR文字识别
Apr 02 Python
tensorflow转换ckpt为savermodel模型的实现
May 25 Python
python中对列表的删除和添加方法详解
Feb 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与MySQL交互使用详解
2006/10/09 PHP
实现了一个PHP5的getter/setter基类的代码
2007/02/25 PHP
PHP生成二维码的两个方法和实例
2014/07/01 PHP
PHP中使用GD库绘制折线图 折线统计图的绘制方法
2015/11/09 PHP
laravel实现分页样式替换示例代码(增加首、尾页)
2017/09/22 PHP
PHP使用反向Ajax技术实现在线客服系统详解
2019/07/01 PHP
thinkphp5 框架结合plupload实现图片批量上传功能示例
2020/04/04 PHP
jquery里的正则表达式说明
2011/08/03 Javascript
使用Nodejs开发微信公众号后台服务实例
2014/09/03 NodeJs
浅谈js中的引用和复制(传值和传址)
2016/09/18 Javascript
jQuery实现自动调用和触发某个事件的方法
2016/11/18 Javascript
详解使用angularjs的ng-options时如何设置默认值(初始值)
2017/07/18 Javascript
react-native使用leanclound消息推送的方法
2018/08/06 Javascript
vue实现搜索功能
2019/05/28 Javascript
ElementUI之Message功能拓展详解
2019/10/18 Javascript
JS 获取文件后缀,判断文件类型(比如是否为图片格式)
2020/05/09 Javascript
详解vue中v-model和v-bind绑定数据的异同
2020/08/10 Javascript
vue单元格多列合并的实现
2020/11/26 Vue.js
Python中的闭包详细介绍和实例
2014/11/21 Python
Python zip()函数用法实例分析
2018/03/17 Python
Python中max函数用于二维列表的实例
2018/04/03 Python
python开发之anaconda以及win7下安装gensim的方法
2019/07/05 Python
pymysql模块的使用(增删改查)详解
2019/09/09 Python
Pytorch 卷积中的 Input Shape用法
2020/06/29 Python
python matplotlib工具栏源码探析二之添加、删除内置工具项的案例
2021/02/25 Python
HTML5 File API改善网页上传功能
2009/08/19 HTML / CSS
Algenist奥杰尼官网:微藻抗衰老护肤品牌
2017/07/15 全球购物
中专生学习生活的自我评价分享
2013/10/27 职场文书
写给女生的道歉信
2014/01/08 职场文书
2014新年元旦活动策划方案
2014/02/18 职场文书
事业单位年度考核评语
2014/12/31 职场文书
写好求职信的技巧解密
2019/05/14 职场文书
创业项目大全(适合在家创业的项目)
2019/08/15 职场文书
jQuery class属性操作addClass()与removeClass()、hasClass()、toggleClass()
2021/03/31 jQuery
Python实现学生管理系统并生成exe可执行文件详解流程
2022/01/22 Python
Zabbix对Kafka topic积压数据监控的问题(bug优化)
2022/07/07 Servers