Python'da ArcGIS imleçlerini büyük tablolarla kullanırken performansı nasıl artırabilirim?


10

Bir dosya coğrafi veritabanında (~ 4000 000 kayıt) oldukça büyük nokta özellik sınıfı var. Bu, 100m çözünürlüğe sahip düzenli bir nokta ızgarasıdır.

Bu katman üzerinde bir tür genelleme yapmam gerekiyor. Bunun için, her noktanın 4 "eski" noktanın ortasında olduğu yeni bir ızgara oluşturuyorum:

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

[*] = orijinal ızgaranın noktası - [o] = yeni ızgaranın noktası

Her yeni noktanın özellik değeri, eski ızgaradaki 4 komşusunun ağırlıklı değerlerine göre hesaplanır. Böylece, yeni ızgaramın tüm noktalarında döngü yapıyorum ve her biri için, komşuları bulmak için (özellik tablosundaki X ve Y değerlerini karşılaştırarak) eski ızgaramın tüm noktalarında döngü yapıyorum. 4 komşu bulunduğunda, döngüden çıkarız.

Burada metodolojik bir karmaşıklık yok ama benim sorunum, ilk testlerime dayanarak, bu komut dosyasının tamamlanması haftalarca sürecek ...

Daha verimli hale getirmek için herhangi bir olasılık görüyor musunuz? Kafamın üstünde birkaç fikir var:

  • X ve Y alanlarını endeksleyin => Bunu yaptım ancak önemli bir performans değişikliği fark etmedim
  • Özniteliğe dayalı bir sorgulama yerine komşuları bulmak için uzamsal sorgulama yapın. Bu gerçekten yardımcı olur mu? ArcGIS'te hangi mekansal fonksiyon yapmalı? Örneğin her yeni noktayı arabelleğe almanın daha verimli olacağından şüpheliyim
  • Unsur sınıfını bir NumPy Dizisine dönüştürün. Bu yardımcı olur mu? NumPy ile şu ana kadar çok çalışmadım ve birisi bana işlem süresini azaltmaya gerçekten yardımcı olabileceğini söylemedikçe içine dalmak istemem
  • Başka herhangi bir şey?

Hangi Arcmap sürümünü kullanıyorsunuz?
Martin

PostGIS'i düşündünüz mü? Bu bir seçenek mi?
Chad Cooper

Bunu unuttuğum için üzgünüm: ArcGIS 10.1 // Python 2.7
Stéphane Henriod

Hayır, PostGIS maalesef bir seçenek değil, ellerim maalesef burada oldukça bağlı ... En iyi ihtimalle Oracle'ı SDE işlevleriyle kullanabilirim
Stéphane Henriod

Yanıtlar:


13

Noktaları bir numpy dizisine beslediyseniz ve komşuları aramak için bir scipy cKDTree kullandıysanız ne olur? Bu tekniği kullanarak birkaç DAKİKA'da çok sayıda nokta (> 20 milyon) olan LiDAR nokta bulutlarını işliyorum. Burada kdtree için ve burada numpy dönüştürme için belgeler var . Temel olarak, x, y'yi bir diziye okursunuz ve dizideki her nokta üzerinde, her bir noktanın belirli bir mesafesindeki (mahalle) nokta indekslerini bularak yinelersiniz. Daha sonra diğer nitelikleri hesaplamak için bu indeksleri kullanabilirsiniz.


bu cevap benimkinden daha iyi
radouxju

Bu fikri seviyorum ama üzerinde çalıştığım iş istasyonunda hiç bir bilgim yok (ve yönetici hakları yok). Bu paketi
kurmayı başarabilirsem

4

Barbarossa ile birlikteyim ... kavisli imleçler çılgınca topal, bu yüzden onları sadece bir masa veya özellik sınıfında tam olarak bir kez geçmek için kullanıyorum. İşi bir döngüde tamamlayamazsam, imleci başka bir tür veri yapısı doldurmak ve bununla çalışmak için kullanırım.

Numpy ile uğraşmak istemiyorsanız , koordinatlarınızı basit bir metin anahtarı olarak kullandığınız basit bir python sözlüğü yapın ve hesaplama için gereken özellikleri sözlük öğesinin değeri olarak bir listeye doldurun .

İkinci adımda, bir noktayı hesaplamak için ihtiyacınız olan değerleri kolayca sözlükten alarak elde edebilirsiniz (bu, öğelerin sözlükleri hashindexinden dolayı inanılmaz derecede hızlıdır).


Aslında sözlüklerdeki fikrinizi seviyorum ve yeni uyguladım. Gerçekten çok daha iyi çalışır ... Ben gerçekten bir row.insertRow () ile sonuçları yazana kadar ... Ben de bu kısmı nasıl geliştirebilirim?
Stéphane Henriod

Benzer bir sorun yaşadım, 14 milyon civarında 10.000 puan seçmek zorunda kaldım. ve sonra silin. arcpy.cursors saniyede sadece 1 veya 2 nokta silebilir (!). bu yüzden sadece bir saniyede tek bir SQL DELETE deyimi ile silmek için pyodbc modülü yüklü. SQL üzerinde GÜNCELLEME, sadece nitelikleri değiştirmek istediğiniz sürece size çok fazla iyileştirme getirecektir ... yine de ek python modülleri yüklemeniz gerekecek ... ama buna değer.
Jürgen Zornig

2

Düzenli bir ızgara için, raster formatında çalışmak çok daha verimli olmalıdır. İlk ızgarayı bir raster haline dönüştürün, bilinear enterpolatör kullanarak aynı çözünürlükte yeniden örnekleyebilirsiniz, ancak çıktı görüntünüzü X ve Y'de 1/2 piksel kaydırırsınız ve yine de noktalara ihtiyacınız varsa tekrar noktalara dönebilirsiniz.

DÜZENLEME: karmaşık kararlar kuralları için, ihtiyacınız olan alanların her birini yeni bir raster bandı olarak dönüştürebilirsiniz, daha sonra bu bantların dört kopyasını yaparsınız ve rasterinizi 4 yönde 1/2 piksel (+50, - 50), (+ 50, + 50), (-50, -50) ve (-50, + 50). Ardından normal harita cebirini kullanabilirsiniz


Teşekkürler Aslında bu çözümü düşündüm ama raster biçiminde ise yeni değeri hesaplamak nasıl / nasıl uygulamak emin değilim. Açıklamama izin verin: her yeni nokta (veya yeni raster hücre) için değerini şu şekilde hesaplamam gerekir: Komşularının her birinin değerini alırım. Bu değerlerin her birinin yeni noktaya belirli bir değer verme olasılığı vardır. Örneğin, bir komşunun 202 değeri varsa, o zaman 3 (1 ağırlığında) veya 11 (5 ağırlığında) değerini verecektir. Sonra tüm 4 komşu için özetliyoruz ve yeni değeri buluyoruz ... Bunun çok açık olup olmadığından emin değil ...
Stéphane Henriod

Not: Yeni değeri bulmak için yapılan hesaplama, bazı durumlarda, Raster yaklaşımını
atabilecek

ağırlıklı toplamınız için sadece iki rastere ihtiyacınız vardır: biri ağırlıkların ve değerlerin ürününü yeniden örneklediğiniz, ikincisi sadece ağırlıkları yeniden örneklediğiniz. Birincisini ikinciye bölerseniz, ağırlıklı toplamınızı elde edersiniz.
radouxju

1
@ StéphaneHenriod - bir öneri olarak, bu ek özellikleri eklemek için soruyu düzenlemeyi düşünebilirsiniz. İlk soru göz önüne alındığında, bu cevabın tonlarca mantıklı olduğunu düşünüyorum, ancak bu yeni bilgilerle Barbarossa'nın cevabı iyi görünüyor.
nicksan

2

Yardımlarınız için herkese teşekkürler!

Sonunda bu sorunu çözmek için çok pythonic olmayan bir yol buldum ... Aslında en fazla zaman harcayan şey, her noktanın 4 komşusunu bulmaktı. X ve Y özniteliklerini kullanmaktan ziyade (ya bir imleçle ya da bir python sözlüğü gibi başka bir veri yapısında), ArcGIS aracını Generate near table kullanarak kullandım . Bunun uzamsal indekslerden faydalandığını ve endeksi kendim uygulamak zorunda kalmadan performansların çok daha yüksek olduğunu varsayıyorum.


0

İmleçlerle ilgili sorun, aralarında yalnızca bir şekilde dolaşabilmeniz ve geri dönememenizdir. Tavsiye edilmemesine rağmen, yeniden ziyaret etmeyi planlıyorsanız, güzellikleri bir yapıya doldurabilirsiniz.

Özelliklerinizi tek bir döngüde işleyebildiyseniz, geri dönüşümü etkinleştirmenizi öneririm. Arama özellik sınıfı işlevinizde, python'un eski özellikler tarafından ayrılan belleği yeniden kullanmasını ve imleçteki özelliklerin daha hızlı geçişini sağlayan bir parametredir. Izgarayı% 80 daha hızlı işleyebilirsiniz.

Sorun, bir imleçten alınan özellikleri depolamayı planlıyorsanız geri dönüşümü etkinleştirememenizdir.


Bu "geri dönüşüm imleci" konusunu araştırmak istiyorum ancak ESRI Yardımı'nda herhangi bir belge bulamıyorum. Bağlantın var mı Arama İmlecinin geri dönüşüm parametresi yoktur. Select_by_Attribute öğesinde böyle bir parametre yoktur. ENV'de hiçbir şey görmüyorum.
klewis


1
"Tekrarlı imleçleri" ArcPy aracılığıyla, sadece çekirdek Arcobjects ile kullanılabilir sanmıyorum.
klewis
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.