Duplikate aus einem Shape-File/ Tabelle filtern

Wenn du dir nicht sicher bist, in welchem der anderen Foren du die Frage stellen sollst, dann bist du hier im Forum für allgemeine Fragen sicher richtig.
Antworten
DaBRain
User
Beiträge: 4
Registriert: Dienstag 3. August 2010, 14:23

Hallo liebe Forenuser,

ich hoffe es gibt diesen Thread noch nicht, über die Suche habe ich nämlich nichts finden können ;)

Zunächst einmal bin ich ein ziemlicher Neuling im Bereich der Python - Programmierung, so entschuldige ich mich schonmal vorweg für dumme Fragen ;)
Nun zu meinem Problem:
Ich habe mir im Zusammenhang mit der GIS Bearbeitungssoftware ArcGIS 9.3 ein Pythonskript geschrieben bzw. es versucht, um aus einem Shapefile bzw. einer Tabelle mit den Spalten X, Y, Z und noch ein paar anderen für jede Zeile die X,Y,Z Koordinaten von verschiedenen Punkten herauszulesen. Das hat soweit auch ganz gut geklappt. Allerdings habe ich nun einige Punkte, die doppelt vorkommen, also die gleichen X,Y,Z Werte haben. Um diese herauszufinden, habe ich nun 2 Schleifen gemacht und diese miteinander verglichen. Das hat in soweit auch geklappt, sodass ich wenn ich den Code durchlaufen lasse, am Ende eine Aufzählung der Punkte bekomme, die doppelt sind. Allerdings werden mir nun, wenn ich z.B. einen Punkt habe, der 3mal vorkommt, alle drei Punkte angezeigt. Ich möchte aber im Prinzip jeden Punkt mit den Koordinaten X,Y,Z jeweils nur einmal angezeigt bekommen. Leider bin ich auch nach längerer Internetrecherche nicht fündig geworden und hoffe, dass mir hier im Forum jmd einen hilfreichen Tipp geben könnte.
Im folgenden der Code den ich geschrieben habe:

Code: Alles auswählen

import arcgisscripting          # import der Library
gp=arcgisscripting.create(9.3)  # geoprocessor zum import von funktionen
gp.workspace="C:/Temp/"          # workspace

filename = "duply.txt"         # name der Datei 

#print "Writing to file: %s" % filename

cur=gp.SearchCursor("fur_model.shp", "", "", "X,Y,Z,Tri_Index")      # Durchsuchen der Datei nach den Spalten X, Y, Z

#cur3=gp.SearchCursor("fur_model.shp", "", "", "X,Y,Z,Tri_Index")

# Get the first feature in the searchcursor
#
row = cur.next()

#row3=cur3.next()

#file = open(filename, 'w')  # öffnen des Files, mode write

          # schreiben von i (da zahl--> string)
        # schreiben von neuer zeile


while row:      # schleife über die tabelle
    
    cur2=gp.SearchCursor("fur_model.shp", "", "", "X,Y,Z,Tri_Index")
    row2=cur2.next()
   
    while row2:
        if row.X == row2.X and row.Y == row2.Y and row.Z == row2.Z:
            print "Doublette: " , row.X , row.Y, row.Z
            
        row2=cur2.next()
        
    row = cur.next()  
#file.write(")")             
#file.close()                    # file schließen
  
print "neuer versuch"
Grüße DaB
Benutzeravatar
Hyperion
Moderator
Beiträge: 7478
Registriert: Freitag 4. August 2006, 14:56
Wohnort: Hamburg
Kontaktdaten:

Man könnte einfach ein ein set aus den Punkten erstellen.

Code: Alles auswählen

In [5]: s = set(((1, 2, 3), (1, 2, 3)))

In [6]: s
Out[6]: set([(1, 2, 3)])
Alternativ könnte man per "in" Operator testen, ob ein Punkt bereits in der Menge enthalten ist:

Code: Alles auswählen

In [7]: l = (
   ...: [1, 2, 3],
   ...: [1, 2, 2],
   ...: [1, 2, 3]
   ...: )

In [8]: res = []

In [9]: for point in l:
   ...:     if not point in res:
   ...:         res.append(point)
   ...:
   ...:

In [10]: res
Out[10]: [[1, 2, 3], [1, 2, 2]]
Ich denke ich würde da eher auf die Lösung mittels set zurückgreifen, die bei großen Datenmengen bestimmt auch wesentlich performanter ist. (Sets arbeiten afaik auf Hashing-Basis!)
encoding_kapiert = all(verstehen(lesen(info)) for info in (Leonidas Folien, Blog, Folien & Text inkl. Python3, utf-8 everywhere))
assert encoding_kapiert
ms4py
User
Beiträge: 1178
Registriert: Montag 19. Januar 2009, 09:37

Hyperion hat geschrieben:Sets arbeiten afaik auf Hashing-Basis!
Jop, tun sie:
http://docs.python.org/library/stdtypes.html#set hat geschrieben:The elements of a set must be hashable
„Lieber von den Richtigen kritisiert als von den Falschen gelobt werden.“
Gerhard Kocher

http://ms4py.org/
Benutzeravatar
cofi
Python-Forum Veteran
Beiträge: 4432
Registriert: Sonntag 30. März 2008, 04:16
Wohnort: RGFybXN0YWR0

Als Verbesserung der Alternative, koennte man dort auch ein Set benutzen. Duerfte einfacher sein, wenn Daten mit den Punkten assoziert sind.
DaBRain
User
Beiträge: 4
Registriert: Dienstag 3. August 2010, 14:23

danke für schnelle antwort.

könntest du mir kurz erklären wofür die 5 bzw 6 in den eckigen klammern steht?
und wie genau funktioniert dieses "set"? kann ich dann die while schleife löschen oder füge ich das in und out in die while schleife ein?

grüße
Benutzeravatar
Hyperion
Moderator
Beiträge: 7478
Registriert: Freitag 4. August 2006, 14:56
Wohnort: Hamburg
Kontaktdaten:

Vergiss alles mit IN und OUT usw. Das sind nur Formattierungen der ipython-Shell (die sehr zu empfehlen ist btw!). Alles nach dem ":" ist dann echter Python-Code.
encoding_kapiert = all(verstehen(lesen(info)) for info in (Leonidas Folien, Blog, Folien & Text inkl. Python3, utf-8 everywhere))
assert encoding_kapiert
DaBRain
User
Beiträge: 4
Registriert: Dienstag 3. August 2010, 14:23

und wo müsste ich dann die drei zeilen in meinem pythoncode einfügen?
Benutzeravatar
cofi
Python-Forum Veteran
Beiträge: 4432
Registriert: Sonntag 30. März 2008, 04:16
Wohnort: RGFybXN0YWR0

Ungetesteter Schnippsel:

Code: Alles auswählen

import arcgisscripting          # import der Library
gp=arcgisscripting.create(9.3)  # geoprocessor zum import von funktionen
gp.workspace="C:/Temp/"          # workspace

filename = "duply.txt"         # name der Datei 

cur=gp.SearchCursor("fur_model.shp", "", "", "X,Y,Z,Tri_Index")
row = cur.next()
seen_coords = set()

while row:
    current_coordinate = (row.X, row.Y, row.Z)
    if current_coordinate in seen_coords:
        print "Doublette: %s %s %s" % current_coordinate
    else:
        seen_coords.add(current_coordinate)
    row = cur.next()
BlackJack

Verbesserungsvorschlag für die Schleife:

Code: Alles auswählen

import arcgisscripting

gp = arcgisscripting.create(9.3)
gp.workspace = 'C:/Temp/'

cursor = gp.SearchCursor('fur_model.shp', '', '', 'X,Y,Z,Tri_Index')
seen_coords = set()
for row in iter(cursor.next, None):
    current_coordinate = (row.X, row.Y, row.Z)
    if current_coordinate in seen_coords:
        print 'Doublette: %s %s %s' % current_coordinate
    else:
        seen_coords.add(current_coordinate)
Wobei ich jetzt annehme, dass die `cursor.next()`-Methode den Wert `None` liefert wenn keine Datensätze mehr vorhanden sind. Falls das ein anderer Wert ist, muss man das zweite Argument von `iter()` entsprechend anpassen.
DaBRain
User
Beiträge: 4
Registriert: Dienstag 3. August 2010, 14:23

Super,

es hat nun funktioniert :)

vielen Dank für die Hilfe

PS: ich habe einfach nur die erste Schleife genommen...
Antworten