Structured Array, Vergleich mit mehreren Feldern?

mit matplotlib, NumPy, pandas, SciPy, SymPy und weiteren mathematischen Programmbibliotheken.
Antworten
p90
User
Beiträge: 198
Registriert: Donnerstag 22. Juli 2010, 17:30

Hi,

gibt es bei numpy structured arrays eine Möglichkeit, mehrere Felder auf einen Schlag zu vergleichen?
Bsp:

Code: Alles auswählen

import numpy
pos = numpy.array([(1,1,1), (1,2,3), (1,1,4)],
dtype=[('x',numpy.float32),('y',numpy.float32),('z',numpy.float32)])
Nun Möchte ich alle Einträge, die x = 1 und y = 1 haben.
Das kann man so machen:

Code: Alles auswählen

tmp = pos[pos["x"]==1]
xy_gleich = tmp[tmp["y"]==1]
Ich würde das nun gerne in einem Rutsch machen.
Dachte eigentlich, dass es dann so gehen müsste:

Code: Alles auswählen

xy_gleich = pos[pos[["x","y"]] == (1,1)]
tut es aber nicht, da der innere Vergleich nicht Elementweise ausgeführt wird.
Meine Frage ist nun:
Wie bekomme ich das hin?

schöne Grüße,

p91
Sirius3
User
Beiträge: 17747
Registriert: Sonntag 21. Oktober 2012, 17:20

@p90: Du willst eine UND-Verknüpfung

Code: Alles auswählen

xy_gleich = pos[(pos["x"] == 1) & (pos["y"] == 1)]
p90
User
Beiträge: 198
Registriert: Donnerstag 22. Juli 2010, 17:30

Hi,

hm, das hatte ich befürchtet.
Die Lösung ist bei mir leider nicht so schön aber um das zu erklären muss ich jetzt doch etwas weiter Aushohlen ^^.

Also, ich mache das ganze nicht nur für x=1 und y=1 sondern für alle vorkommenden Kombinationen.
Danach habe ich ja einen z-Array von dem ich dann z.B. die Gaussverteilung berechne.
Nur, ich hab in meinem Fall nicht nur eine z-Achse sondern eher 10 und nicht nur x und y sondern ca. 5 Parameter.

Deshalb hatte ich gehofft sowas machen zu können:

Code: Alles auswählen

import numpy
pos = numpy.array([(1,1,1), (1,2,3), (1,1,4), (1,1,45), (1,2,23)],
dtype=[('x',numpy.float32),('y',numpy.float32),('z',numpy.float32)])
a = ["x", "y"]
for values in numpy.unique(pos[a]):
    tmp = pos[pos[a]==values]
Wenn das aber nicht geht, werde ich es wohl so machen müssen:

Code: Alles auswählen

import numpy
pos = numpy.array([(1,1,1), (1,2,3), (1,1,4), (1,1,45), (1,2,23)],
dtype=[('x',numpy.float32),('y',numpy.float32),('z',numpy.float32)])
a = ["x", "y"]
for values in numpy.unique(pos[a]):
    tmp = pos
    for i in range(len(a)):
        tmp = tmp[tmp[a[i]] == values[i]] 
Aber hüpsch und übersichtlich ist anders.

Trotzdem vielen Dank für die Antwort!
BlackJack

@p90: Schau Dir mal das `return_inverse`-Argument von `numpy.unique()` an.

Edit: Ungetestet:

Code: Alles auswählen

#!/usr/bin/env python
# coding: utf8
from __future__ import absolute_import, division, print_function
import numpy as np


def main():
    pos = np.array(
        [(1, 1, 1), (1, 2, 3), (1, 1, 4), (1, 1, 45), (1, 2, 23)],
        dtype=[('x', np.float32), ('y', np.float32), ('z', np.float32)]
    )
    a = ['x', 'y']
    coordinates, indexes = np.unique(pos[a], return_inverse=True)
    for i, coordinate in enumerate(coordinates):
        tmp = pos[indexes == i]
        print(coordinate, tmp)


if __name__ == '__main__':
    main()
p90
User
Beiträge: 198
Registriert: Donnerstag 22. Juli 2010, 17:30

@BlackJack

Wunderbar! Das war genau das was ich gesucht habe!
Herzlichen Dank!
Antworten