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 相关文章推荐
Pyramid添加Middleware的方法实例
Nov 27 Python
python冒泡排序简单实现方法
Jul 09 Python
Python实现统计代码行的方法分析
Jul 12 Python
Django视图之ORM数据库查询操作API的实例
Oct 27 Python
python DataFrame获取行数、列数、索引及第几行第几列的值方法
Apr 08 Python
Python post请求实现代码实例
Feb 28 Python
python实现批量转换图片为黑白
Jun 16 Python
Pandas中DataFrame基本函数整理(小结)
Jul 20 Python
pycharm2020.2 配置使用的方法详解
Sep 16 Python
OpenCV-Python使用cv2实现傅里叶变换
Jun 09 Python
Python使用psutil库对系统数据进行采集监控的方法
Aug 23 Python
PYTHON 使用 Pandas 删除某列指定值所在的行
Apr 28 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
星际中的相关伤害
2020/03/04 星际争霸
php zend 相对路径问题
2009/01/12 PHP
php cli配置文件问题分析
2015/10/15 PHP
php 防止表单重复提交两种实现方法
2016/11/03 PHP
深入理解PHP的远程多会话调试
2017/09/21 PHP
JQuery textlimit 显示用户输入的字符数 限制用户输入的字符数
2009/05/14 Javascript
jquery中eq和get的区别与使用方法
2011/04/14 Javascript
jQuery 常见操作实现方式和常用函数方法总结
2011/05/06 Javascript
js实现弹窗插件功能实例代码分享
2013/12/12 Javascript
jQuery+css实现百度百科的页面导航效果
2014/12/16 Javascript
PHP守护进程实例
2015/03/06 Javascript
vue2.0开发实践总结之疑难篇
2016/12/07 Javascript
利用vue实现模态框组件
2016/12/19 Javascript
javascript监听页面刷新和页面关闭事件方法详解
2017/01/09 Javascript
JavaScript队列的应用实例详解【经典数据结构】
2017/04/12 Javascript
详解Vue.js搭建路由报错 router.map is not a function
2017/06/27 Javascript
[01:30]我们共输赢 完美世界城市挑战赛开启全新赛季
2019/04/19 DOTA
python判断字符串编码的简单实现方法(使用chardet)
2016/07/01 Python
简单掌握Python中glob模块查找文件路径的用法
2016/07/05 Python
Python并发之多进程的方法实例代码
2018/08/15 Python
Python多线程同步---文件读写控制方法
2019/02/12 Python
Python从函数参数类型引出元组实例分析
2019/05/28 Python
pyqt5 实现多窗口跳转的方法
2019/06/19 Python
Python3+Appium实现多台移动设备操作的方法
2019/07/05 Python
详解将Python程序(.py)转换为Windows可执行文件(.exe)
2019/07/19 Python
python 接口实现 供第三方调用的例子
2019/08/13 Python
ubuntu上安装python的实例方法
2019/09/30 Python
scrapy数据存储在mysql数据库的两种方式(同步和异步)
2020/02/18 Python
Html5实现首页动态视频背景的示例代码
2019/09/25 HTML / CSS
俄罗斯珠宝市场的领导者之一:Бронницкий ювелир
2019/10/02 全球购物
介绍一下Java中标识符的命名规则
2014/02/03 面试题
优秀乡村医生事迹材料
2014/05/28 职场文书
司法所长先进事迹
2014/06/02 职场文书
小学秋季运动会报道稿
2014/09/30 职场文书
初中班干部工作总结
2015/08/10 职场文书
阿里云服务器部署RabbitMQ集群的详细教程
2022/06/01 Servers