在带有大表的Python中使用ArcGIS游标时如何提高性能?


10

我在文件地理数据库中有一个很大的点要素类(〜4 000 000条记录)。这是具有100m分辨率的常规点网格。

我需要在这一层上进行某种概括。为此,我创建了一个新网格,其中每个点位于4个“旧”点的中间:

 *     *     *     *
    o     o     o
 *     *     *     *
    o     o     o
 *     *     *     *

[*] =原始网格点-[o] =新网格点

每个新点的属性值都是基于旧网格中其4个相邻点的加权值来计算的。因此,我在我的新网格的所有点上循环,并针对它们中的每一个,在我的旧网格的所有点上循环,以查找邻居(通过比较属性表中的X和Y的值)。一旦找到4个邻居,我们就会跳出循环。

这里没有方法上的复杂性,但是我的问题是,根据我的第一个测试,该脚本将持续数周才能完成...

您是否有提高效率的可能性?我脑海中浮现出一些想法:

  • 索引字段X和Y =>我这样做了,但是没有注意到任何明显的性能变化
  • 进行空间查询以查找邻居,而不是基于属性的查询。这真的有帮助吗?ArcGIS中应该执行哪些空间功能?我怀疑,例如,缓冲每个新点会更有效
  • 将要素类转换为NumPy数组。有帮助吗?到目前为止,我与NumPy的合作并不多,除非有人告诉我这可能真的有助于减少处理时间,否则我不愿涉足其中
  • 还要别的吗?

您正在使用哪个版本的Arcmap?
马丁

您考虑过PostGIS吗?那是一个选择吗?
乍得·库珀

对不起,我忘了说:ArcGIS的10.1 // Python 2.7版
斯特凡Henriod

不,PostGIS的是不幸的是不是一种选择,我的手都不幸在这儿住绑......充其量我可以使用Oracle与SDE功能
斯特凡Henriod

Answers:


13

如果将这些点输入到numpy数组中并使用粗糙的cKDTree查找邻居该怎么办。我使用这种技术在多个MINUTES中处理了具有大量点(> 2000万个)的LiDAR点云。有文档这里的kdtree和这里的numpy的转换。基本上,您将x,y读入数组,并在数组中的每个点上进行迭代,以找到每个点在一定距离(相邻)内的点的索引。您可以使用这些索引来计算其他属性。


这个答案比我的要好
radouxju 2014年

我喜欢这个主意,但是我在工作的工作站上不知所措(并且没有管理员权限)。如果我设法得到安装这个包,然后我给它一个尝试
斯特凡Henriod

4

我和Barbarossa在一起...弧形游标非常la脚,所以我只用它们一次遍历表或要素类一次。如果我无法在一个周期内完成工作,则可以使用游标填充其他类型的数据结构并进行处理。

如果您不想麻烦numpy,只需制作一个简单的python 字典,在其中将坐标用作简单的文本键,然后将要计算的属性填写到列表中,作为字典项的值。

在第二步中,您只需从字典中获取点即可轻松获得计算点所需的值(由于项的字典hashindex的原因,这非常快)。


我实际上很喜欢您的词典想法,而我只是实现了它。它的确工作得好得多……直到我实​​际用row.insertRow()编写结果为止……知道如何改善这一部分吗?
斯特凡Henriod

我有一个类似的问题,我必须从14 Mio中选择大约10.000点。然后将其删除。arcpy.cursors每秒只能删除大约1或2个点(!)。所以我安装了pyodbc模块,仅用一秒钟的时间用一条SQL DELETE语句删除了它们。只要您只想修改属性,通过SQL进行升级将为您带来很多改进……尽管如此,您仍必须安装其他python模块……但这是值得的。
尔根·佐尼格(JürgenZornig),2014年

2

对于常规网格,以栅格格式工作应该更加有效。将您的第一个栅格转换为栅格,您可以使用双线性插值器以相同的分辨率重新采样,但是将输出图像在X和Y方向上移动1/2像素,如果仍然需要点,则再次返回点。

编辑:对于复杂的决策规则,您可以将所需的每个字段转换为新的栅格波段,然后制作这些波段的四个副本,然后将栅格在4个方向上移动1/2像素(+ 50,- 50),(+ 50,+ 50),(-50,-50)和(-50,+ 50)。然后您可以使用常规地图代数


谢谢,我实际上已经想到了此解决方案,但是我不确定如果采用栅格格式,是否/如何实现新值的计算。让我解释一下:对于每个新点(或新栅格像元),我需要这样计算其值:我采用其每个相邻点的值。这些值中的每一个都有给新点赋予特定值的可能性。例如,如果一个邻居的值为202,则它将给出值3(权重为1)或值11(权重为5)。然后,我们总结了所有4个邻居,找到新的价值...不知道这是否是很清楚...
斯特凡Henriod

PS:找到新的价值的计算可以在某些情况下,可以根据两个属性,不只是一个,这可能会放弃光栅方法
斯特凡Henriod

对于加权总和,您只需要两个栅格:一个栅格用于对权重和值的乘积进行重新采样,第二栅格仅对权重进行采样。如果将第一个除以第二个,将获得加权和。
radouxju 2014年

1
@StéphaneHenriod-作为建议,您可以考虑编辑问题以添加这些其他规范。对于最初的问题,我认为这个答案很有道理,但是有了这些新信息,Barbarossa的答案看起来不错。
nicksan 2014年

2

谢谢大家的帮助!

我终于找到了解决该问题的非常非Python的方法...实际上,花费最多计算时间的是找到每个点的4个邻居。我没有使用X和Y属性(既可以使用圆弧形光标,也可以使用其他数据结构(例如python字典)使用),而最终使用了ArcGIS工具Generate near table。我认为这利用了空间索引的优势,并且性能显然要高得多,而无需我自己实现索引。


0

游标的问题在于,您只能以一种方式循环游标,而不能返回。尽管不建议这样做,但是如果您打算重新访问这些特征,则可以将其填充到一个结构中。

如果您能够在一个循环中处理功能,则建议启用回收。它是搜索要素类函数上的一个参数,该参数使python可以重用由旧要素分配的内存,并使光标中的要素遍历更快。您可以将网格处理速度提高80%。

问题是,如果您计划存储从游标中检索到的要素,则无法启用回收。


我想探索这个“回收游标”主题,但是在ESRI帮助中找不到任何文档。你有链接吗?搜索光标没有回收参数。Select_by_Attribute没有这样的参数。我在ENV中什么也看不到。
klewis 2014年


1
我不认为只有核心Arcobjects可以通过ArcPy使用“重用光标”。
klewis 2014年
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.