动作 将多个LAZ点云文件读取到Dask DataFrame。
问题
将LAZ(压缩)解压缩到LAS(未压缩)需要大量内存。不同的文件大小和由Dask创建的多个进程会导致MemoryError
。
尝试
我尝试限制遵循指南的工作人员数量,但似乎没有效果。
from distributed import Client, LocalCluster
cluster = LocalCluster(n_workers=3)
client = Client(cluster)
dfs = [load(file) for file in lasfiles]
df = dd.from_delayed(dfs, meta=meta)
df = df.repartition(npartitions=len(df) // part_size)
df.to_parquet('/diskstation/geomaat/geomaat3d/raw', compression='GZIP')
问题 如何以非标准格式加载如此大量的数据?
示例
以下示例是我当前的实现。它将每5个输入文件分组,以限制最多5个并行的解压缩过程。然后重新分区并写入Parquet以进行进一步处理。对我来说,这个实现似乎完全忽略了Dask的观点。
from laspy.file import File
import numpy as np
import pandas as pd
import dask.dataframe as dd
from dask.delayed import delayed
@delayed
def load(file):
with File(file.as_posix(), mode='r') as las_data:
las_df = pd.DataFrame(las_data.points['point'], dtype=float)
return las_df
meta = pd.DataFrame(np.empty(0, dtype=[('X',float),('Y',float),('Z',float),('intensity',float),('raw_classification',int)]))
lasfile_dir = Path('/data/las/')
lasfiles = sorted(list(lasfile_dir.glob('*.laz')))
part_size = 5000000
for idx, sublasfiles in enumerate([lasfiles[i:i+5] for i in range(0,len(lasfiles),5)]):
try:
dfs = [load(file) for file in sublasfiles]
df = dd.from_delayed(dfs, meta=meta)
df = df.repartition(npartitions=len(df) // part_size)
df.to_parquet('/data/las/parquet/'+str(idx), compression='GZIP')
答案 0 :(得分:1)
你的实施对我来说似乎很好。
我在这里要改变的一件事是我会避免调用len(df)
,这会强制计算整个数据帧(没有读取全部数据帧的方法就无法确定数据帧的长度文件)。
为了清楚起见,Dask将无法在您的load
函数内并行化(它没有LAZ文件的概念),因此您的并行性将受到您拥有的文件数量的限制。