Julia内核项目记录(一)

0 阅读2分钟

Julia内核项目

1、处理ASCII文本文件

1.1、读取文本文件🔥

准备处理文本格式的点云文件,常见的有CSV和.xyz,xyz和csv基本一致,就先写csv的处理逻辑。

Julia的性能可以接近C/C++,当然我得写的足够规范,才能发挥出Julia的优势。处理文本格式的点云文件,可以预见,真正耗时的读取部分,我的主要目的肯定不是处理文本点云文件,工程上las/laz,e57,ply都比文本格式好。

但是,我需要准备处理文本格式的点云文件,所以还是得写。一方面能够熟悉Juia,一方面可以为后续的功能打基础。对于工程设计上,我经验很少,很多只能摸着石头过河了~😄

df = CSV.read("p1.csv", DataFrame;
 select=[1,2,3], delim = ',') 
 # 只读取前三列

delim是函数参数,如果知道csv的分隔符,直接指定会更好,delim不指定,函数会读取前十行数据,进行推断,所以直接指定会更省一点时间。

2、函数🔥

函数实现对Z值按最小值归一化,和按高度提取切片

流程 1.对Z列数据,求出最小值,2.归一化到这个最小值 3.按Z值大小,提取前两列

function extract_slice(DF::DataFrame,limit1::Float64,limit2::Float64)
    z_min = minimum(DF.Z); #julia的minimum自身优化过,性能很好
    DF_1 = DF.Z .- z_min; #广播机制
    mask = (limit1 .< DF_1 ) .& (DF_1 .< limit2);
    DF_output = DF[mask, :] #导出切片点云
    return DF_DBH_output
end

这其实不是最快的实现,但是性能足够使用了,DF_1 是DF.Z的副本,创造副本加剧开销!但是我不想破坏原Dataframe。

只得好好说到的广播机制和向量化操作,在提取切片点云时,我们需要将DF.Z 减去z_min值,这其实就是一个广播操作,在Julia中,广播操作可以通过 .- 符号实现。好处就是在大量数据面前快!

.<表示对limit1 和 DF_1 中的对应元素逐一进行 < 比较,生成一个布尔数组,其中必须指定limit1和limit2是一个标量,标量会自动和DF_1这个向量对齐。

✨其实还有其他方法实现,利用subset函数:

output = subset(DF, :Z_norm =>
 ByRow(x -> limit1 < x < limit2))

💡使用Byrow()函数,将Z列中的值与limit1和limit2进行比较。x -> limit1 < x < limit2匿名函数用法。这里:Z_norm是提前归一化的Z列。

ByRow()函数很好,不用复制列,直接在ByRow()函数中使用列名,能减少内存。

3、总结

实际应用中,归一化拿出函数外边去做,里边用subset函数,能减少内存。况且调用切片点云的时候,一般都已经归一化完了。😃