Seite 1 von 2

Attributtabelle sortieren

Verfasst: Montag 9. August 2010, 08:18
von Michi_J
Hallo,

kann mir jemand sagen, wie ich mit Hilfe eines Python-Skriptes eine Attributtabelle nach einer bestimmten Spalte, wo die Zahlenwerte noch durcheinaner gewürfelt sind, aufsteigend sortieren kann?

Re: Attributtabelle sortieren

Verfasst: Montag 9. August 2010, 08:22
von lutz.horn
Kannst Du ein paar mehr Details posten?

Re: Attributtabelle sortieren

Verfasst: Montag 9. August 2010, 08:38
von Michi_J
Ich habe ein Punkte-Shapefile mit verschiedenen Spalten und möchte jetzt die gesamte Tabelle nach einer bestimmten Spalte aufsteigend sortieren, wie es z.B. in der Attributtabelle mit rechtem Mausklick auf den Spaltenkopf und dann 'Sort Ascending' möglich ist

Re: Attributtabelle sortieren

Verfasst: Montag 9. August 2010, 08:53
von BlackJack
@Michi_J: Attributtabelle? Mausklick? Reden wir jetzt von einer Datenstruktur? Einer grafischen Anwendung? Welche?

Ansonsten gibt es auf Python's Listentyp eine `sort()`-Methode und es gibt eine `sorted()`-Funktion um aus beliebigen iterierbaren Objekten eine sortierte Liste zu generieren.

Wenn die "natürliche" Ordnung der Elemente nicht die richtige ist, haben sowohl die Methode als auch die Funktion ein Argument mit dem Namen `key` bei dem man eine Funktion angeben kann, die aus einem Element einen Sortierschlüssel generieren muss. Bei einfachen Sachen sind ``lambda``-Funktionen nützlich. Und eventuell auch `functools.partial()` in Verbindung mit `itemgetter()` oder `attrgetter()` aus dem `operator`-Modul.

Re: Attributtabelle sortieren

Verfasst: Montag 9. August 2010, 09:12
von Michi_J
das mit der Attributtabelle war nur zum besseren Verständnis gedacht, damit klar wird, was ich machen will.
Ich bin ziemlich neu hier und noch recht hilflos - bitte um Verzeihung.

Ich kann ja schon mal meinen Code posten, was ich mir bisher überlegt habe und bin über jede Anregung sehr dankbar, wie gesagt, ich bin noch ziemlich grün hinter den Ohren...

Code: Alles auswählen

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

# table = Polyline0Punkte.shp --> an dieser Stelle sollte die Table eingelesen werden
import operator

def sort_table(table, col=2)
    return sorted(table, key=operator.itemgetter(col))

# nach dem sortieren soll die sortierte Table in eine Liste gepackt werden - ich weiß noch nicht, wie das funktioniert

sooo... das sieht zwar noch seeehr nach Anfänger aus, der keine Ahnung hat, aber das bin ich auch. Bitte um Hilfe!!!
Danke!

Re: Attributtabelle sortieren

Verfasst: Montag 9. August 2010, 09:39
von BlackJack
@Michi_J: `sorted()` liefert schon eine Liste als Ergebnis, das Problem im letzten Kommentar im Quelltext löst sich also von alleine.

Ich würde die Funktion etwas allgemeiner formulieren, also ohne `table` im Namen und nicht mit einer so ziemlich willkürlich erscheinenden Spalte als Defaultargument.

Code: Alles auswählen

def sorted_by_index(iterable, index)
    return sorted(iterable, key=operator.itemgetter(index))

Re: Attributtabelle sortieren

Verfasst: Montag 9. August 2010, 09:50
von Michi_J
@ BlackJack

muss der Input-Datensatz dann auch schon eine Liste sein? oder wie kann ich meine Table einlesen? Also ich hab jetzt mal meine Tabelle sozusagen in eine Liste eingefügt. Diese soll nun eben sortiert werden

Hier mein Vorschlag - dieser läuft aber nicht, immer Syntax-Fehlermeldung

Code: Alles auswählen

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

 
cur=gp.SearchCursor("Polyline0Punkte.shp", "", "", "FID, FID_DREIEC, ORIG_FID, POINT_X,POINT_Y,POINT_Z,Tri_Index")      # Durchsuchen der Datei nach den Spalten X, Y, Z


#get the first value
row = cur.next()

# Iterate through the rows in the cursor
#
liste = list()
while row:
    current_FID = (row.FID)
    FID_Dreieck = (row.FID_DREIEC)
    FID_Polyline = (row.ORIG_FID)
    current_coordinate = (row.POINT_X, row.POINT_Y, row.POINT_Z)
    liste.append(current_FID)
    liste.append(FID_Dreieck)
    liste.append(FID_Polyline)
    liste.append(current_coordinate)

    row = cur.next()
    
import operator

def sort_table(iterable, index)
    return sorted(iterable, key=operator.itemgetter(2))

print liste
    

Re: Attributtabelle sortieren

Verfasst: Montag 9. August 2010, 09:55
von cofi
Michi_J hat geschrieben:Hier mein Vorschlag - dieser läuft aber nicht, immer Syntax-Fehlermeldung
Traceback bitte posten!

Du willst im uebrigen `key=operator.itemgetter(index)` nutzen. Und den Import schreibt man ueblicherweise in den Anfang des Moduls.

Re: Attributtabelle sortieren

Verfasst: Montag 9. August 2010, 10:00
von Michi_J
aber muss ich den Index dann nicht definieren? Ich will ja die Liste nach dem 2. Eintrag sortieren...

Re: Attributtabelle sortieren

Verfasst: Montag 9. August 2010, 10:09
von cofi
Du musst den Index sowieso uebergeben, also kannst du ihn auch benutzen.
Wenn du einen Shortcut nutzen willst kannst du folgendes machen:

Code: Alles auswählen

import functools
def sort_with_index(iterable, index)
    return sorted(iterable, key=operator.itemgetter(index))

sort_table = functools.partial(sort_with_index, index=2)
Und der Traceback?

Re: Attributtabelle sortieren

Verfasst: Montag 9. August 2010, 10:24
von Michi_J
bitte nicht lachen ... was ist der Traceback?

Re: Attributtabelle sortieren

Verfasst: Montag 9. August 2010, 10:26
von Klip
Die komplette Fehlermeldung.

Re: Attributtabelle sortieren

Verfasst: Montag 9. August 2010, 10:26
von Michi_J
und wie erkennt das Script, welche liste es sortieren soll?

Re: Attributtabelle sortieren

Verfasst: Montag 9. August 2010, 10:27
von Michi_J
Fehlermeldung: invalid syntax

Re: Attributtabelle sortieren

Verfasst: Montag 9. August 2010, 10:30
von BlackJack
@Michi_J: Das `iterable` Argument muss nur iterierbar sein. Darum habe ich es ja so genannt. ;-) Es geht also alles was bei `iter()` einen Iterator über die zu sortierenden Objekte liefert oder nach dem ``in`` in einer ``for``-Schleife verwendet werden kann.

Dein Programm hat ein logisches Problem: Du steckst die einzelnen Datensätze nicht als *ein* Objekt in die `liste`. Schau Dir mal an was da rauskommt. Viele von den Elementen dürften auf einen Versuch eines Indexzugriffs nicht so reagieren wie Du das wohl erwartest.

Aus der ``while``-Schleife würde ich eine ``for``-Schleife machen. Dann muss man nicht an zwei verschiedenen Stellen die `next()`-Methode selber aufrufen:

Code: Alles auswählen

for row in iter(cur.next, None):
    # ...

Der Traceback ist der Stapelabzug der bei Fehlermeldungen ausgegeben wird. Das Wort steht da doch auch ganz am Anfang:

Code: Alles auswählen

>>> 1 / 0
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
ZeroDivisionError: integer division or modulo by zero
Der enthält eine Auflistung aller Beteiligten Funktionen in der Aufrufhierarchie, die zu dem Fehler geführt haben, in der Regel auch mit den Zeilen aus den beteiligten Quelltextdateien. Das hilft beim Fehlersuchen.

Das Skript erkennt nicht welche Liste sortiert werden soll. Das musst Du schon sagen indem Du die Funktion mit den passenden Argumenten aufrufst und das Ergebnis zum Beispiel an einen Namen bindest.

Re: Attributtabelle sortieren

Verfasst: Montag 9. August 2010, 10:30
von Michi_J
hier nochmals mein Code:

Code: Alles auswählen

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

 
cur=gp.SearchCursor("Polyline0Punkte.shp", "", "", "FID, FID_DREIEC, ORIG_FID, POINT_X,POINT_Y,POINT_Z,Tri_Index")      # Durchsuchen der Datei nach den Spalten X, Y, Z


#get the first value
row = cur.next()

# Iterate through the rows in the cursor
#
liste = list()
while row:
    current_Eintrag = (row.FID, row.FID_DREIEC, row.ORIG_FID, row.POINT_X, row.POINT_Y, row.POINT_Z)
    liste.append(current_Eintrag)
    liste.append(' ')

    row = cur.next()
    
#import operator

#def sort_table(iterable, index)
    #index = 2
    #return sorted(iterable, key=operator.itemgetter(index))
import functools
def sort_with_index(iterable, index)
    return sorted(iterable, key=operator.itemgetter(index))

sort_table = functools.partial(sort_with_index, index=2)



Re: Attributtabelle sortieren

Verfasst: Montag 9. August 2010, 10:41
von BlackJack
Der Traceback sollte am Ende eher so aussehen:

Code: Alles auswählen

   File "<file>", line 28
     def sort_with_index(iterable, index)
                                         ^
 SyntaxError: invalid syntax
Da gibt es also auch eine Quelltextzeile. Und einen "Pfeil" (^), der auf die Stelle zeigt, an welcher der Compiler nicht mehr weiter weiss. Und nun schau doch nochmal in der Dokumentation, was genau an der Stelle bei einer Funktionsdefinition erwartet wird.

Beim nächsten Versuch wird Dir wahrscheinlich ein `NameError` begegnen. Und wenn der behoben ist, und Du die Funktion auch mal tatsächlich aufrufst ist ein ``IndexError: string index out of range`` der nächste wahrscheinliche Kandidat. Aber eins nach dem anderen…

Re: Attributtabelle sortieren

Verfasst: Montag 9. August 2010, 11:34
von Michi_J
worin liegt jetzt noch der Fehler, dass das Skript nicht läuft?

Code: Alles auswählen

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

 
cur=gp.SearchCursor("Polyline0Punkte.shp", "", "", "FID, FID_DREIEC, ORIG_FID, POINT_X,POINT_Y,POINT_Z,Tri_Index")      # Durchsuchen der Datei nach den Spalten X, Y, Z


#get the first value
row = cur.next()

# Iterate through the rows in the cursor
#
liste = list()
for row in iter(cur.next, none):

    def sort_table(iterable, Index)
        return sorted(iterable, key=operator.itemgetter(index))
    sorted_table = operator(sort_table, 2)
    
    current_Eintrag = (row.FID, row.FID_DREIEC, row.ORIG_FID, row.POINT_X, row.POINT_Y, row.POINT_Z)
    liste.append(current_Eintrag)
    
    liste.append(' ')

    row = cur.next()
    

#def sort_with_index(iterable, index)
    #return sorted(iterable, key=operator.itemgetter(index))

#sort_table = functools.partial(sort_with_index, index=2)


print liste
    

Re: Attributtabelle sortieren

Verfasst: Montag 9. August 2010, 11:49
von Rebecca
Anstatt auf geratewohl Dinge zu aendern, solltest du mal die Fehlermeldung verstehen! BlackJack hat es dir doch erklaert!

Re: Attributtabelle sortieren

Verfasst: Montag 9. August 2010, 11:59
von Michi_J
Ich krieg gar keinen Traceback-Eintrag im Python shell, da vorher schon ein Fenster erscheint in welchem genau folgende Mitteilung steht: There's an error in your program: invalid syntax