Seite 1 von 1
ndarray auf einzelne Werte zu greifen
Verfasst: Mittwoch 4. Mai 2011, 15:20
von Xynon1
Ich habe ein numpy.array, welches eine beliebige Tiefe haben kann und ich möchte einzelne Wert(integer) auslesen und einem anderen gleich großen Array zuornden. Bisher habe ich immer per
die Zuordnung gemacht, da ich die Wert a, b und c* gestellt bekomme. Das Problem ist nun, das die Arrays zwar immer die gleich Größe haben, aber halt auch 2d- oder 4d-Arrays sein können.
Nur blicke ich gerade nicht, wie ich am besten die Indizes dynamisch auslesen kann. Hätte hierzu jemand einen Tipp?
* Die Werte entsprechen keinem Muster und entspringen einem Tuple, dessen Länge gleich der Dimensionsgröße des ndarrays ist.
Re: ndarray auf einzelne Werte zu greifen
Verfasst: Mittwoch 4. Mai 2011, 15:44
von EyDu
Hallo.
Entweder verstehe ich nicht, auf was du hinaus möchtest oder suchst du tatsächlich nur folgendes?
Sebastian
Re: ndarray auf einzelne Werte zu greifen
Verfasst: Mittwoch 4. Mai 2011, 16:18
von Xynon1
Man kann schon echt beschränkt sein.
Danke, gibt es sowas in der Art eigentlich auch für normale Listen ?
Re: ndarray auf einzelne Werte zu greifen
Verfasst: Mittwoch 4. Mai 2011, 16:36
von pillmuncher
Aber freilich!
[EDIT] Geh, a so a Schmarrn...
Re: ndarray auf einzelne Werte zu greifen
Verfasst: Mittwoch 4. Mai 2011, 16:39
von Xynon1
Schade

Re: ndarray auf einzelne Werte zu greifen
Verfasst: Mittwoch 4. Mai 2011, 22:21
von Leonidas
Xynon1 hat geschrieben:Schade

"Freilich" bedeutet "Natürlich", "Na klar"...
Re: ndarray auf einzelne Werte zu greifen
Verfasst: Mittwoch 4. Mai 2011, 22:29
von Hyperion
Leonidas hat geschrieben:
"Freilich" bedeutet "Natürlich", "Na klar"...
Wobei man das auch als Nicht-Bayer verstehen sollte! Ich fand den Kommentar ja "pfundig"

Re: ndarray auf einzelne Werte zu greifen
Verfasst: Donnerstag 5. Mai 2011, 07:38
von Xynon1
Ich hatte das eigentlich als Ironie aufgefasst. Das die Syntax nicht bei Listen existiert ist mir schon klar, die geänderte Slice-Syntax von dem numpy.ndarray ist schließlich in C implementiert, oder ?
Wie setzt man sowas sonst um?
Re: ndarray auf einzelne Werte zu greifen
Verfasst: Donnerstag 5. Mai 2011, 08:16
von pillmuncher
Nachdem ich bei meiner ersten Anwort weder genau gelesen, noch genau nachgedacht habe - in Python würde ich das in etwa so machen:
Code: Alles auswählen
class Lizzy(list):
def __getitem__(self, index):
if type(index) == tuple:
tmp = self
for each in index:
tmp = list.__getitem__(tmp, each)
return tmp
else:
return list.__getitem__(self, index)
# etc.
li = Lizzy([['a', 'b', 'c'], ['d', 'e', 'f']])
print li[1]
print li[1,1]
Ergebnis:
Lizzy.__setitem__ muss man dann analog dazu bauen.
Gruß,
Mick.
Re: ndarray auf einzelne Werte zu greifen
Verfasst: Donnerstag 5. Mai 2011, 08:27
von Xynon1
Stimmt so gehts natürlich.
Sollte man aber aus "if type(index) == tuple:" nicht noch "if isinstance(index, tuple):" machen?
bzw.es könnte eigentlich jede Sequenz sein.
Re: ndarray auf einzelne Werte zu greifen
Verfasst: Donnerstag 5. Mai 2011, 08:41
von pillmuncher
Du hast recht. Vielleicht sollte man sogar "if isinstance(index, (list, tuple)):" schreiben.
Re: ndarray auf einzelne Werte zu greifen
Verfasst: Donnerstag 5. Mai 2011, 08:43
von Xynon1
Ist mir auch gerade aufgefallen, eigentlich könnte es jede Sequenz sein. Gibt es dafür in Python ein "Erkennungsmerkmal" ?
Ansonsten sollte man vieleicht sogar besser auf Integer prüfen, da dieser ja wirklich als Index benötigt wird.
Re: ndarray auf einzelne Werte zu greifen
Verfasst: Donnerstag 5. Mai 2011, 08:50
von pillmuncher
So, das noch:
Code: Alles auswählen
def __setitem__(self, index, item):
if isinstance(index, (list, tuple)):
list.__setitem__(self[index[:-1]], index[-1], item)
else:
list.__setitem__(self, index, item)
Erkennungsmerkmal: Bei neueren Pythons wäre das wohl "isinstance(index, collections.Sequence)"
Prüfung auf int: noch besser, hast recht.
Schönen Tag,
Mick.
Re: ndarray auf einzelne Werte zu greifen
Verfasst: Donnerstag 5. Mai 2011, 09:48
von Xynon1
Sieht gut aus, auch wenn man es warscheinlich selten bis nie gebrauchen wird, da wenn man größere Listen/Arrays hat, wohl doch gleich numpy nimmt.
Dennoch, danke, wieder was gelernt

Re: ndarray auf einzelne Werte zu greifen
Verfasst: Donnerstag 5. Mai 2011, 10:03
von EyDu
Oder aber in kurz:
Code: Alles auswählen
>>> l=[[[0,1,2],[3,4,5]],[[6,7,8],[9,10,11]]]
>>> reduce(lambda data, index: data[index], (0,1,2), l)
5
Und auf Integers als Key würde ich auch nicht testen, das erzeugt nur unnötige Einschränkungen. Vielleicht möchte man so etwas machen:
Code: Alles auswählen
>>> reduce(lambda data, index: data[index], (0,1,slice(1,3)), l)
[4, 5]
Oder so etwas:
Code: Alles auswählen
>>> d=[[{"spam":1, "eggs":2}, {"foo":3, "bar":4}], [{"baz":5, "argh":6}]]
>>> reduce(lambda data, index: data[index], (0,1,"foo"), d)
3
Re: ndarray auf einzelne Werte zu greifen
Verfasst: Donnerstag 5. Mai 2011, 10:39
von Xynon1
@EyDu
Das sieht doch nochmal um längen schicker aus. Könnte man die lambda-Funktion nicht noch durch list.__getitem__ ersetzen?
Obwohl ich Wörterbücher nicht damit mischen würde, hättest du natürlich recht, daran und slices habe ich nicht gedacht und vergess jetzt bloß nicht "Ellipsis" noch mit einzubauen
Aber wie gestaltet man damit das setzen des anderen Liste/Arrays?
Re: ndarray auf einzelne Werte zu greifen
Verfasst: Donnerstag 5. Mai 2011, 11:43
von BlackJack
@Xynon1: Dann funktioniert es ja nur mit Listen. Für's setzen müsste man sich eine Funktion schreiben die sich auf die vorhandene Abstützt.
Re: ndarray auf einzelne Werte zu greifen
Verfasst: Donnerstag 5. Mai 2011, 11:52
von Xynon1
Stimmt, und ich nehme mal an das "type(data).__getitem__" auch nicht angebracht ist, weil es im Vergleich zu der lambda-Funktion etwas unschöner ausieht.
Re: ndarray auf einzelne Werte zu greifen
Verfasst: Donnerstag 5. Mai 2011, 21:33
von pillmuncher
Dann also so?
Code: Alles auswählen
class Lizzy(list):
def __getitem__(self, index):
if isinstance(index, (int, slice)):
return list.__getitem__(self, index)
else:
return reduce(list.__getitem__, index, self)
def __setitem__(self, index, item):
if isinstance(index, (int, slice)):
list.__setitem__(self, index, item)
else:
list.__setitem__(self[index[:-1]], index[-1], item)
li = Lizzy([['a', 'b', 'c'], ['d', 'e', 'f']])
print li[1]
print li[1,1]
print li[slice(1,3)]
print li[1, slice(1,3)]
li[0,2] = li[1,1]
print li
li[0, slice(0,3)] = li[1, slice(0,2)]
print li
Ergebnis:
Code: Alles auswählen
['d', 'e', 'f']
e
[['d', 'e', 'f']]
['e', 'f']
[['a', 'b', 'e'], ['d', 'e', 'f']]
[['d', 'e'], ['d', 'e', 'f']]
Re: ndarray auf einzelne Werte zu greifen
Verfasst: Freitag 6. Mai 2011, 08:15
von Xynon1
Verhält sich aber irgendwie anders als ich erwarten würde:
Code: Alles auswählen
>>> li = Lizzy([['a', 'b', 'c'], ['d', 'e', 'f']])
>>> la = numpy.array(li)
>>> la
array([['a', 'b', 'c'],
['d', 'e', 'f']],
dtype='<U1')
>>> li
[['a', 'b', 'c'], ['d', 'e', 'f']]
>>> la[slice(0, 2), 0]
array(['a', 'd'],
dtype='<U1')
>>> li[slice(0, 2), 0]
['a', 'b', 'c']
>>>
Mit den Slice-Ausdrücken kommt es so nicht klar, war zwar auch nicht die Bedingung, aber man würde halt was anderes erwarten.