2016-04-21 6 views
2

Ich spiele mit Tables-Objekt von astropy.table-Modul.Python-Astropie: Tabellen- und Spaltenobjekte

Das Stück Code zeigt die Art der Daten, mit denen ich zu tun:

In [44]: table    
Out[44]: 
<Table length=9> 
defocus source Chi2 xcentroid ycentroid FWHMx FWHMy Peak 
float32 float32 float32 float32 float32 float32 float32 float32 
------- ------- ------- --------- --------- ------- ------- ------- 
    -0.3  0.0 346.648 2056.5  55.82 11.8635 11.8635 182.277 
    -0.3  4.0 148.302 2056.49 1911.02 6.66554 6.66554 299.074 
    -0.3  8.0 347.208 2056.51 3922.99 6.83129 6.83129 326.476 
    -0.26  0.0 318.489 2056.5 55.8803 10.206 10.206 195.055 
    -0.26  4.0 152.501 2056.51 1911.02 6.9012 6.9012 244.817 
    -0.26  8.0 285.845 2056.49 3922.99 7.7939 7.7939 236.194 
    -0.22  0.0 264.113 2056.5 55.9053 8.79704 8.79704 187.376 
    -0.22  4.0 163.228 2056.5 1911.02 2.43716 2.43716 402.182 
    -0.22  8.0 230.017 2056.5 3922.99 6.70312 6.70312 235.376 

In [45]: type(table)  
Out[45]: astropy.table.table.Table 

In [46]: cols=table.columns 

In [47]: type(cols) 
Out[47]: astropy.table.table.TableColumns 

In [48]: type(cols[0]) 
Out[48]: astropy.table.column.Column 

In [50]: mylist_1 = [x for x in cols] 

In [51]: mylist_2 = [cols[k] for k in range(len(cols))] 

In [52]: type(mylist_1[0]) 
Out[52]: str 

In [53]: type(mylist_2[0]) 
Out[53]: astropy.table.column.Column 

In [54]: mylist_1[0] 
Out[54]: 'defocus' 

In [55]: mylist_2[0] 
Out[55]: 
<Column name='defocus' dtype='float32' length=9> 
-0.3 
-0.3 
-0.3 
-0.26 
-0.26 
-0.26 
-0.22 
-0.22 
-0.22 

Ich hatte erwartet, dass die beiden Linien:

mylist_1 = [x for x in cols] 

und

mylist_2 = [cols[k] for k in range(len(cols))] 

würde de genau das gleiche (das zweite ist weniger elegant), aber es nicht, wie Sie in den obigen Ausgaben sehen können (mylist_1 c enthält nur die Spaltennamen und nicht die Spalten selbst). Warum ist das so? Gibt es etwas, was ich nicht wirklich über mein "Cols" -Objekt verstehe?

Vielen Dank für Ihre Einblicke.

(Ich stieß darauf, während ich versuchte, meine Tabelle in eine Fit-Datei zu schreiben - mit astropy.io.fits - die erfordert, eine entsprechende Spaltenliste zu erstellen, die nicht so offensichtlich ist, wie man erwarten würde ...)

+0

Es gibt nicht viel über FITS-Dateien, die "offensichtlich" ist (wie mein Lieblingsbeispiel, die fehlende Unterstützung für vorzeichenlose Ganzzahlen :) – Iguananaut

Antwort

0

Ihre Schleifen iterieren etwas anders (aber äquivalent) über die Spalten. Aber hängen Sie verschiedene Dinge in das Listenverständnis ein. Die Säulen sind dict -like, so dass sie einen Index und ein zugehöriges Element haben:

eine Tabelle wie folgt vor:

from astropy.table import Table 

data_rows = [(1, 2.0, 'x'), 
      (4, 5.0, 'y'), 
      (5, 8.2, 'z')] 
t = Table(rows=data_rows, names=('a', 'b', 'c'), meta={'name': 'first table'}, 
      dtype=('i4', 'f8', 'S1')) 
cols=t.columns 

Sie iterieren die Spaltenindizes unter Verwendung:

[x for x in cols] 
# ['a', 'b', 'c'] 

oder

[k for k in range(len(cols))] 
# [0, 1, 2] 

Diese scheinen anders als cols[0] == cols['a'], also sind dies nur zwei verschiedene Möglichkeiten, Ihre Spalten zu indizieren.

Aber wenn man über die tatsächlichen Spalten iterieren wollen nicht ihre Indizes könnten Sie tun:

[cols[x] for x in cols] 
# [<Column name='a' dtype='int32' length=3>1 4 5, 
# <Column name='b' dtype='float64' length=3>2.0 5.0 8.2, 
# <Column name='c' dtype='bytes1' length=3> x y z] 

oder:

[cols[k] for k in range(len(cols))] 
# [<Column name='a' dtype='int32' length=3>1 4 5, 
# <Column name='b' dtype='float64' length=3>2.0 5.0 8.2, 
# <Column name='c' dtype='bytes1' length=3> x y z] 

Dieses Mal haben wir die indizierte Spalte tatsächlich einfügen statt Einfügen Der Index.

Dies ist jedoch kein Mittel zu Ihrem Ende mit der Umstellung auf FITS, aber Sie können Ihre Tabelle immer direkt in einem ihrer Formate speichern, siehe their supported formats.

zum Beispiel auf einen fits Schreiben ist so einfach wie ein:

t.write('new_table.fits') 

oder

t.write('new_table.fits', format='fits') 
+0

war es für mich überhaupt nicht offensichtlich, dass ich über die Indizes iteriere, indem ich [x von x in Spalten] mache. Weil bei einer klassischen Liste (zB L = [8,12,4,1]) [x für x in L] über die Elemente der Liste iteriert, nicht die Indizes. Aber ich verstehe, dass meine Astro-Tabelle ein anderes Objekt ist und sich dank Vinces Antwort auch nicht wie eine einfache Liste verhält. Prost. – samR

+0

@samR es ist mehr wie Iterieren über ein Wörterbuch als Iterieren über eine Liste. Es wird noch komplizierter durch die Tatsache, dass Spalten numerische und String-Indizierung ermöglichen. Aber ich hoffe, ich habe es zu Ihrer Zufriedenheit erklärt. :) – MSeifert

+0

ja du hast. Und ich kann jetzt meine Fit-Dateien einfach schreiben! :-) – samR

0

Die Tabelle "astropy.table.table.TableColumns" ist ein definiertes Element des Astropie-Pakets. Es ist eine Instanz der Klasse TableColumns und sollte grundsätzlich nicht mit dem Iterator "cols [k]" oder "in cols" darauf zugreifen können.

Aber in einer Klasse können Sie die Methode enthält() und getitem() definieren das Verhalten dieser beiden Anfragen zu beschreiben. Siehe https://infohost.nmt.edu/tcc/help/pubs/python/web/special-methods.html

Hier scheint es, dass die definierten Verhaltensweisen nicht zu einer klassischen Liste von Element ähnlich sind. Vielleicht ist ein Dokument über Astro-Klassen verfügbar.

+0

es ist __contains __() und __getitem __(), ich kann nicht die Unterstriche haben . – Vince

2

Das astropy.table.table.TableColumns Objekt (über das columns Attribut zugegriffen wird) ist ein geordneten dict, keine Liste. Aus diesem Grund gibt [x for x in cols] eine Liste der Spaltennamen (genauso wie die Iteration über ein normales Diktat die Schlüssel liefert, nicht die Werte).

Der Einfachheit halber unterstützt es auch indexierten Zugriff und Slicing wie col[0] oder cols[1:3]. Aber obwohl es Listen-ähnlichen Zugriff unterstützt, ist TableColumns in erster Linie ein Diktat.

In PR #4394 wird eine neue Methode hinzugefügt, die cols_list = [x for x in t.itercols()] unterstützt.