Benötige Unterstützung bei NumPy

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
E1986
User
Beiträge: 19
Registriert: Samstag 3. Mai 2014, 17:43

Ich habe folgendes Problem und frage mich, wie man das mit NUMPY am Besten lösen kann:
Mein Input (data )lautet folgendermaßen:

[['aa' 'A' 'B' 'C' 'D' 'E' 'F' 'G' 'H' 'I' 'J']
['bb' '25.18' '' '28.19' '32.53' '33.18' '18.29' '20.56' '21.04' '' '19.56']
['1' '650' '0' '0' '0' '1120' '790' '950' '820' '0' '950']
['2' '650' '0' '0' '0' '1120' '790' '950' '820' '0' '950']
['3' '650' '0' '0' '0' '1120' '790' '950' '820' '0' '950']
['4' '650' '0' '320' '680' '1120' '790' '950' '820' '0' '950']
['5' '650' '0' '320' '680' '1120' '790' '950' '820' '0' '950']
['6' '650' '0' '320' '680' '1120' '790' '950' '820' '0' '950']
['7' '650' '0' '0' '0' '1120' '790' '950' '820' '0' '950']
['8' '650' '0' '0' '0' '1120' '790' '950' '820' '0' '950']
['9' '650' '0' '0' '0' '1120' '790' '950' '820' '0' '950']
['10' '650' '0' '0' '0' '1120' '790' '950' '820' '0' '950']]

Jetzt nehm ich die erste Spalte raus und unterteile den Input in drei Teile:

aa=data[0:1,1:] (also die erste Zeile ohne aa)
bb=data[1:2,1:] (also die zweite Zeile ohne bb, hier sind einige Werte bewusst nicht vorhanden!)
c_array=data[2:,1:] (Zeilen 3 bis 12 ohne die vorderen Ziffern)

Und jetzt möchte ich für alle Zeilen aus c_array und alle darin enthaltenen Werte > 0 die zugehörigen Werte aus b_list haben. (es kann auch sein, obwohl in c_array > 0, dass es in b_list keine Wert gibt, also steht dann auch nichts in der Ergebnisliste)

Bsp. c_array[3] -> also ['650' '0' '320' '680' '1120' '790' '950' '820' '0' '950']
Als Ergebnis soll hier als Liste herauskommen: '25.18' '28.19' '32.53' '33.18' '18.29' '20.56' '21.04' '19.56'
(nochmal: es kann ich sein, obwohl in c_array > 0, dass es in b_list keinen zugehörigen Wert gibt, also steht dann auch nichts in der Ergebnisliste)

Habt ihr Vorschläge wie ich da rangehen? Vor allem der Anfang um in c_array einzusteigen bereitet mit Kopfzerbrechen.
Hab jetzt:

for i in range(len(c_array)):
if i > 0:
1. Ist das als Anfang okay?
2. Wie „sagen“ ich ihm dann (Syntax), dass er mir für jede Zeile die zugehörigen Werte aus b_list ausgeben soll, bzw. in eine Liste schreiben soll!?
3. Das ganze sollte per NumPy gemacht werden.

Hat jemand Vorschläge/Syntax zu der Problematik?
Besten Dank schonmal.
BlackJack

@E1986: Als erstes würde ich von diesen Arrays mit Python-Objekten (Zeichenketten) auf Arrays umsteigen die tatsächlich Zahlen enthalten. Denn *dafür* ist Numpy eigentlich gedacht. Das sollte man im Grunde schon beim einlesen machen, denn erst ein Array mit Zeichenketten in den Speicher zu laden, um das *dann* komplett im Speicher noch mal in ein Array mit Zahlen umzuwandeln ist nicht besonders speichereffizient.

Dann wäre es praktisch wenn Du Beispieldaten zeigst, dass man die auch einfach weiterverarbeiten kann. Das geht mit der `str()`-Darstellung von Numpy-Arrays nicht wirklich gut, weil man die Daten erst überarbeiten/parsen muss. Die `repr()`-Darstellung wäre da schon einfacher. Als Vergleich:

Code: Alles auswählen

In [14]: print str(A)
[['a' 'b']
 ['42' '23']]

In [15]: print repr(A)
array([['a', 'b'],
       ['42', '23']], 
      dtype='|S2')
Beim zweiten müsste man nur `array` importieren oder ``numpy.`` schreiben und könnte das dann per kopieren und einfügen in einer Shell wieder zu einem Array-Objekt machen.

Ad 1: Das ist als Anfang nicht okay. ``for i in range(len(sequence)):`` ist in Python ein „anti pattern”. Man kann direkt über die Elemente iterieren. Und sollte man tatsächlich zusätzlich den Index benötigen kann man sich den mit der `enumerate()`-Funktion generieren lassen. Man braucht nur ganz ganz selten tatsächlich nur den Index als Laufvariable.

Wenn die erste Zeile vom `c_array` ignoriert werden soll, dann würde man auch eher ein entsprechendes „slice” vom Array erstellen welches die erste Zeile nicht enthält, statt den Index für den Test in *jeder* Zeile zu benutzen ob es nicht die erste ist. Wobei ich jetzt auch nicht sehe warum Du die erste Zeile ignorieren möchtest? Aus der Beschreibung geht das nicht hervor.

Ansonsten würde man wohl am besten die Indizes mit der `nonzero()`-Methode erstellen und als Index in das `bb`-Array verwenden. Und wenn in `bb` NaNs vorkommen können, wäre es vielleicht geschickt sowohl `bb` als auch das `c_array` vorher komplett von diesen Spalten zu befreien. Ansonsten müsste man die nachher einzeln aus den Ergebnissen rausfiltern.

Habe kurz über die Daten geschaut, und da kommt der Fall anscheinend gar nicht vor, sprich wo in der zweiten Zeile ein '' steht, sind im Rest nur '0'en in der Spalte. Test- und Beispieldaten sollten auch die ganzen Sonderfälle tatsächlich enthalten, die man berücksichtigen will oder muss.

Hast Du schon das Numpy-Tutorial durchgerarbeitet? Insbesondere ohne das Wissen was man alles für Indexwerte in „slices” verwenden kann, wirst Du nicht weit kommen.
E1986
User
Beiträge: 19
Registriert: Samstag 3. Mai 2014, 17:43

Hey BlackJack. Vielen Dank für deine Antwort und deine Hinweise. Ich hatte auch geschrieben, dass ich die erste Spalte ignorieren möchte, nicht die erste Zeile. UND: Wo finde ich das NumPy-Tutorial?
BlackJack

@E1986: Das Numpy-Tutorial findet man im Internet. Ausgehend von der Numpy-Webseite. Die unter http://www.numpy.org/ zu finden ist. Da gibt's gleich auf der Startseite unter der Überschrift „Getting Started” eine Reihe von Links zur Dokumentation und unter anderem zum Numpy-Tutorial.
E1986
User
Beiträge: 19
Registriert: Samstag 3. Mai 2014, 17:43

DANKE!!
BlackJack

Ich habe mal ein wenig herum probiert. Mit diesen Eingabedaten (in der dritten Zeile steht mit Absicht ein Wert != 0 in einer Spalte in der in der zweiten Zeile nichts steht):

Code: Alles auswählen

aa,A,B,C,D,E,F,G,H,I,J
bb,25.18,,28.19,32.53,33.18,18.29,20.56,21.04,,19.56
1,650,42,0,0,1120,790,950,820,0,950
2,650,0,0,0,1120,790,950,820,0,950
3,650,0,0,0,1120,790,950,820,0,950
4,650,0,320,680,1120,790,950,820,0,950
5,650,0,320,680,1120,790,950,820,0,950
6,650,0,320,680,1120,790,950,820,0,950
7,650,0,0,0,1120,790,950,820,0,950
8,650,0,0,0,1120,790,950,820,0,950
9,650,0,0,0,1120,790,950,820,0,950
10,650,0,0,0,1120,790,950,820,0,950
Und der Code:

Code: Alles auswählen

#!/usr/bin/env python
from __future__ import print_function
import numpy as np


def load_data(filename):
    data = np.genfromtxt(filename, delimiter=',', skip_header=1)
    return data[0], data[1:]


def main():
    bb, rows = load_data('test.csv')
    # 
    # Remove columns where `bb` has NaN values.  This always includes the
    # very first column because the original data has the 'bb' label in the
    # first cell of the second row.
    # 
    idx = ~np.isnan(bb)
    assert not idx[0]
    bb = bb[idx]
    rows = rows[:, idx]

    for idx in rows > 0:
        print(bb[idx])


if __name__ == '__main__':
    main()
pythonyänu
User
Beiträge: 2
Registriert: Donnerstag 15. Mai 2014, 09:48

So ist das Wesen des Bösen, mit der Zeit kommt alles Übel zum Vorschein!

Dein Problem ist unlösbar! Ich kenne die Kniffe und Tricks! Das kann nicht gut kommen. Rette dich, so lang du noch Zeit hast!!!
Das FBI und die CIA sind dir auf den Fersen! Rette dich, so lang du noch Zeit hast!!!
Gruss
pythonyänu
Benutzeravatar
snafu
User
Beiträge: 6741
Registriert: Donnerstag 21. Februar 2008, 17:31
Wohnort: Gelsenkirchen

pythonyänu hat geschrieben:So ist das Wesen des Bösen, mit der Zeit kommt alles Übel zum Vorschein!

Dein Problem ist unlösbar! Ich kenne die Kniffe und Tricks! Das kann nicht gut kommen. Rette dich, so lang du noch Zeit hast!!!
Das FBI und die CIA sind dir auf den Fersen! Rette dich, so lang du noch Zeit hast!!!
Was es auch ist, du solltest dringend mehr davon nehmen. :)
pythonyänu
User
Beiträge: 2
Registriert: Donnerstag 15. Mai 2014, 09:48

Flieht ihr Narren!!!
Gruss
pythonyänu
BlackJack

Vielleicht solltest Du auch *weniger* nehmen. Oder zumindest mal etwas *anderes*. Es gibt auch nette Sachen die nicht so paranoid machen. ;-)
Antworten