python - 并行读取文件并参数化类参数
问题描述
假设我有一个类,并且想从磁盘并行读取几个文件,并参数化类参数。最正确的方法是什么(以及如何)?
- 主线程应该等待 load_data() 操作结束,然后再发生其他任何事情。
我考虑过线程,因为它只是 I/O 操作。
非并行实现示例(1-Threading):
import pandas as pd
class DataManager(object):
def __init__(self):
self.a = None
self.b = None
self.c = None
self.d = None
self.e = None
self.f = None
def load_data(self):
self.a = pd.read_csv('a.csv')
self.b = pd.read_csv('b.csv')
self.c = pd.read_csv('c.csv')
self.d = pd.read_csv('d.csv')
self.e = pd.read_csv('e.csv')
self.f = pd.read_csv('f.csv')
if __name__ == '__main__':
dm = DataManager()
dm.load_data()
# Main thread is waiting for load_data to finish.
print("finished loading data")
解决方案
在大多数情况下,I/O 操作不受 CPU 限制,因此使用多个进程是多余的。使用多个线程可能很好,但pb.read_csv
不仅读取文件,而且解析它可能是 CPU 限制的。我建议您在最初为此目的制作时立即使用 asyncio 从磁盘读取文件。这是执行此操作的代码:
import asyncio
import aiofiles
async def read_file(file_name):
async with aiofiles.open(file_name, mode='rb') as f:
return await f.read()
def read_files_async(file_names: list) -> list:
loop = asyncio.get_event_loop()
return loop.run_until_complete(
asyncio.gather(*[read_file(file_name) for file_name in file_names]))
if __name__ == '__main__':
contents = read_files_async([f'files/file_{i}.csv' for i in range(10)])
print(contents)
该函数read_files_async
返回文件内容列表(字节缓冲区),您可以将其传递给pd.read_csv
.
我认为只优化文件读取就足够了,但是您可以与多个进程并行解析文件内容(线程和异步不会提高解析过程的性能):
import multiprocessing as mp
NUMBER_OF_CORES = 4
pool = mp.Pool(NUMBER_OF_CORES)
pool.map(pb.read_csv, contents)
您应该NUMBER_OF_CORES
根据您的机器规格进行设置。
推荐阅读
- c# - 如何调整图像大小以适合图片框?
- javascript - 停止不必要的组件渲染
- android - 如何将多个cmake目标添加到android ndk项目
- sharepoint - 如何以编程方式重命名 SharePoint 文件
- xml - 基于数组元素,在 XSLT 1.0 中使用 for-each 时拆分为两个数组
- c# - 错误:“System.NullReferenceException:对象引用未设置为对象的实例。” 在图像加载 .NET Core
- android - 升级Android APP Gradle 版本时出现Filoreader 升级问题
- javascript - 如何使 InputNumber antd 元素失焦?
- android - 在模块中发现重复的类
- c# - 使用restsharp调用具有双重身份验证的api