侯体宗的博客
  • 首页
  • Hyperf版
  • beego仿版
  • 人生(杂谈)
  • 技术
  • 关于我
  • 更多分类
    • 文件下载
    • 文字修仙
    • 中国象棋ai
    • 群聊
    • 九宫格抽奖
    • 拼图
    • 消消乐
    • 相册

python频繁写入文件时提速的方法

Python  /  管理员 发布于 7年前   190

问题背景:有一批需要处理的文件,对于每一个文件,都需要调用同一个函数进行处理,相当耗时。

有没有加速的办法呢?当然有啦,比如说你将这些文件分成若干批,每一个批次都调用自己写的python脚本进行处理,这样同时运行若干个python程序也可以进行加速。

有没有更简单的方法呢?比如说,我一个运行的一个程序里面,同时分为多个线程,然后进行处理?

大概思路:将这些个文件路径的list,分成若干个,至于分成多少,要看自己cpu核心有多少,比如你的cpu有32核的,理论上就可以加速32倍。

代码如下:

# -*-coding:utf-8-*-import numpy as npfrom glob import globimport mathimport osimport torchfrom tqdm import tqdmimport multiprocessinglabel_path = '/home/ying/data/shiyongjie/distortion_datasets/new_distortion_dataset/train/label.txt'file_path = '/home/ying/data/shiyongjie/distortion_datasets/new_distortion_dataset/train/distortion_image'save_path = '/home/ying/data/shiyongjie/distortion_datasets/new_distortion_dataset/train/flow_field'r_d_max = 128image_index = 0txt_file = open(label_path)file_list = txt_file.readlines()txt_file.close()file_label = {}for i in file_list:  i = i.split()  file_label[i[0]] = i[1]r_d_max = 128eps = 1e-32H = 256W = 256def generate_flow_field(image_list):  for image_file_path in ((image_list)):    pixel_flow = np.zeros(shape=tuple([256, 256, 2])) # 按照pytorch中的grid来写    image_file_name = os.path.basename(image_file_path)    # print(image_file_name)    k = float(file_label[image_file_name])*(-1)*1e-7    # print(k)    r_u_max = r_d_max/(1+k*r_d_max**2) # 计算出畸变校正之后的对角线的理论长度    scale = r_u_max/128 # 将这个长度压缩到256的尺寸,会有一个scale,实际上这里写128*sqrt(2)可能会更加直观    for i_u in range(256):      for j_u in range(256):        x_u = float(i_u - 128)        y_u = float(128 - j_u)        theta = math.atan2(y_u, x_u)        r = math.sqrt(x_u ** 2 + y_u ** 2)        r = r * scale # 实际上得到的r,即没有resize到256×256的图像尺寸size,并且带入公式中        r_d = (1.0 - math.sqrt(1 - 4.0 * k * r ** 2)) / (2 * k * r + eps) # 对应在原图(畸变图)中的r        x_d = int(round(r_d * math.cos(theta)))        y_d = int(round(r_d * math.sin(theta)))        i_d = int(x_d + W / 2.0)        j_d = int(H / 2.0 - y_d)        if i_d < W and i_d >= 0 and j_d < H and j_d >= 0: # 只有求的的畸变点在原图中的时候才进行赋值          value1 = (i_d - 128.0)/128.0          value2 = (j_d - 128.0)/128.0          pixel_flow[j_u, i_u, 0] = value1 # mesh中存储的是对应的r的比值,在进行畸变校正的时候,给定一张这样的图,进行找像素即可          pixel_flow[j_u, i_u, 1] = value2# 保存成array格式    saved_image_file_path = os.path.join(save_path, image_file_name.split('.')[0] + '.npy')    pixel_flow = pixel_flow.astype('f2') # 将数据的格式转换成float16类型, 节省空间    # print(saved_image_file_path)    # print(pixel_flow)    np.save(saved_image_file_path, pixel_flow)  returnif __name__ == '__main__':  file_list = glob(file_path + '/*.JPEG')  m = 32  n = int(math.ceil(len(file_list) / float(m))) # 向上取整  result = []  pool = multiprocessing.Pool(processes=m) # 32进程  for i in range(0, len(file_list), n):    result.append(pool.apply_async(generate_flow_field, (file_list[i: i+n],)))  pool.close()  pool.join()

在上面的代码中,函数

generate_flow_field(image_list)

需要传入一个list,然后对于这个list进行操作,之后对操作的结果进行保存

所以,只需要将你需要处理的多个文件,切分成尽量等大小的list,然后再对每一个list,开一个线程进行处理即可

上面的主函数:

if __name__ == '__main__':  file_list = glob(file_path + '/*.JPEG') # 将文件夹下所有的JPEG文件列成一个list  m = 32 # 假设CPU有32个核心  n = int(math.ceil(len(file_list) / float(m))) # 每一个核心需要处理的list的数目  result = []  pool = multiprocessing.Pool(processes=m) # 开32线程的线程池  for i in range(0, len(file_list), n):    result.append(pool.apply_async(generate_flow_field, (file_list[i: i+n],))) # 对每一个list都用上面我们定义的函数进行处理  pool.close() # 处理结束之后,关闭线程池  pool.join()

主要是这样的两行代码,一行是

pool = multiprocessing.Pool(processes=m) # 开32线程的线程池

用来开辟线程池

另外一行是

result.append(pool.apply_async(generate_flow_field, (file_list[i: i+n],))) # 对每一个list都用上面我们定义的函数进行处理

对于线程池,用apply_async()同时跑generate_flow_field这个函数,传入的参数是:file_list[i: i+n]

实际上apply_async()这个函数的作用是所有的线程同时跑,速度是比较快的。

扩展:

Python文件处理之文件写入方式与写缓存来提高速度和效率

Python的open的写入方式有:

write(str):将str写入文件

writelines(sequence of strings):写多行到文件,参数为可迭代对象

f = open('blogCblog.txt', 'w') #首先先创建一个文件对象,打开方式为wf.writelines('123456') #用readlines()方法写入文件

运行上面结果之后,可以看到blogCblog.txt文件有123456内容,这里需要注意的是,mode为‘w'模式(写模式),再来看下面代码:

f = open('blogCblog.txt', 'w') #首先先创建一个文件对象,打开方式为wf.writelines(123456) #用readlines()方法写入文件

运行上面代码之后会报一个TypeError,这是因为writelines传入的参数并不是一个可迭代的对象。

以上就是关于python频繁写入文件怎么提速的相关知识点以及扩展内容,感谢大家的阅读。


  • 上一条:
    python字符串替换第一个字符串的方法
    下一条:
    Python中查看变量的类型内存地址所占字节的大小
  • 昵称:

    邮箱:

    0条评论 (评论内容有缓存机制,请悉知!)
    最新最热
    • 分类目录
    • 人生(杂谈)
    • 技术
    • linux
    • Java
    • php
    • 框架(架构)
    • 前端
    • ThinkPHP
    • 数据库
    • 微信(小程序)
    • Laravel
    • Redis
    • Docker
    • Go
    • swoole
    • Windows
    • Python
    • 苹果(mac/ios)
    • 相关文章
    • 在python语言中Flask框架的学习及简单功能示例(0个评论)
    • 在Python语言中实现GUI全屏倒计时代码示例(0个评论)
    • Python + zipfile库实现zip文件解压自动化脚本示例(0个评论)
    • python爬虫BeautifulSoup快速抓取网站图片(1个评论)
    • vscode 配置 python3开发环境的方法(0个评论)
    • 近期文章
    • 在go中实现一个常用的先进先出的缓存淘汰算法示例代码(0个评论)
    • 在go+gin中使用"github.com/skip2/go-qrcode"实现url转二维码功能(0个评论)
    • 在go语言中使用api.geonames.org接口实现根据国际邮政编码获取地址信息功能(1个评论)
    • 在go语言中使用github.com/signintech/gopdf实现生成pdf分页文件功能(0个评论)
    • gmail发邮件报错:534 5.7.9 Application-specific password required...解决方案(0个评论)
    • 欧盟关于强迫劳动的规定的官方举报渠道及官方举报网站(0个评论)
    • 在go语言中使用github.com/signintech/gopdf实现生成pdf文件功能(0个评论)
    • Laravel从Accel获得5700万美元A轮融资(0个评论)
    • 在go + gin中gorm实现指定搜索/区间搜索分页列表功能接口实例(0个评论)
    • 在go语言中实现IP/CIDR的ip和netmask互转及IP段形式互转及ip是否存在IP/CIDR(0个评论)
    • 近期评论
    • 122 在

      学历:一种延缓就业设计,生活需求下的权衡之选中评论 工作几年后,报名考研了,到现在还没认真学习备考,迷茫中。作为一名北漂互联网打工人..
    • 123 在

      Clash for Windows作者删库跑路了,github已404中评论 按理说只要你在国内,所有的流量进出都在监控范围内,不管你怎么隐藏也没用,想搞你分..
    • 原梓番博客 在

      在Laravel框架中使用模型Model分表最简单的方法中评论 好久好久都没看友情链接申请了,今天刚看,已经添加。..
    • 博主 在

      佛跳墙vpn软件不会用?上不了网?佛跳墙vpn常见问题以及解决办法中评论 @1111老铁这个不行了,可以看看近期评论的其他文章..
    • 1111 在

      佛跳墙vpn软件不会用?上不了网?佛跳墙vpn常见问题以及解决办法中评论 网站不能打开,博主百忙中能否发个APP下载链接,佛跳墙或极光..
    • 2016-10
    • 2016-11
    • 2018-04
    • 2020-03
    • 2020-04
    • 2020-05
    • 2020-06
    • 2022-01
    • 2023-07
    • 2023-10
    Top

    Copyright·© 2019 侯体宗版权所有· 粤ICP备20027696号 PHP交流群

    侯体宗的博客