ArraySPALTEN durchsuchen

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.
lena_92
User
Beiträge: 28
Registriert: Donnerstag 24. Juli 2014, 15:00

Hallo,

ein Array ist ein sehr machtvolles Instrument. Man kann sehr viel anstellen.
Auf diesen Seiten habe ich sehr viel dazu gefunden.
http://www.physik.uzh.ch/lectures/infor ... listen.php
http://docs.scipy.org/doc/numpy/referen ... .sort.html

Frage:

Kann man in einem Array nur eine Spalte nach einem Begriff durchsuchen und dann deren komplette Zeile in eine extra Datei kopieren?

Viele Grüße
Lena
Benutzeravatar
MagBen
User
Beiträge: 799
Registriert: Freitag 6. Juni 2014, 05:56
Wohnort: Bremen
Kontaktdaten:

Wenn Du in Numpy ein 2D-Array hast, dann kannst Du sehr einfach auf die Spalten dieses Arrays zugreifen. Du kannst den Inhalt eines Numpy Arrays auch in einem Einzeiler schön formatiert in eine Datei schreiben. Numpy Arrays sind jedoch in erster Linie für Zahlen gemacht. Bei Begriffen denke ich an Strings und Strings würde ich in der Regel nicht mit Numpy Arrays verarbeiten.
a fool with a tool is still a fool, www.magben.de, YouTube
jerch
User
Beiträge: 1669
Registriert: Mittwoch 4. März 2009, 14:19

@lena_92:
Ja das geht mit Listen/Arrays. Frage ist halt, ob man das gewünschte Verhalten einfach erreichen kann (einfach programmiertechnisch umsetzbar und einfach für den Rechner lösbar/Laufzeit). Und bei Stichworten wie Spalten und Suche würde ich da eher an Datenbanken denken als an einfache Indexcontainertypen. Datenbanken sind einfach einsetzbar und bringen von Haus aus Optimierungen für komplexe Suchanfragen mit.
lena_92
User
Beiträge: 28
Registriert: Donnerstag 24. Juli 2014, 15:00

Hallo zusammen,

danke für die Hinweise.
Zu meinem Arrary:
Dieses Array ist schon vorhanden und ich möchte eigentlich ungern dies noch öfters anpacken. Dieses Array beinhalten auch nur Zahlen.
Ich möchte nun in Spalte A nach einer Zahl suchen, und dann die ganze Zeile kopieren.
Mir persönlich fehlt nun dieser Suchbefehl für Spalte A. Kann mir jemand sagen, wo ich dies nachlesen kann.

Grüße
Lena
Benutzeravatar
MagBen
User
Beiträge: 799
Registriert: Freitag 6. Juni 2014, 05:56
Wohnort: Bremen
Kontaktdaten:

Meinst Du sowas:

Code: Alles auswählen

import numpy as np

data_2d = np.arange(24).reshape(4,6)
print(data_2d)
#[[ 0  1  2  3  4  5]
# [ 6  7  8  9 10 11]
# [12 13 14 15 16 17]
# [18 19 20 21 22 23]]

# Zugriff auf 2. Reihe
row_2 = data_2d[1,:] # Kurzform: row_2 = data_2d[1]
print(row_2)
# [ 6  7  8  9 10 11]


# Zugriff auf 4. Spalte:
column_4 = data_2d[:,3]
print(column_4)
# [ 3  9 15 21]

# Wo ist die 15?
find_15 = column_4==15
print(find_15)
# [False False  True False]

 # http://docs.scipy.org/doc/numpy/reference/routines.sort.html
row_index = np.argwhere(find_15)[0,0] # [0,0]: es koennte ja mehrere Fundstellen geben.
print(row_index)
# 2
row_with_value15 = data_2d[row_index]
print(row_with_value15)
# [12 13 14 15 16 17]

# oder direkter:
print( data_2d[find_15,:])
# [[12 13 14 15 16 17]]
Hier gibt's ein bischen was zu Numpy-Arrays:
http://docs.scipy.org/doc/numpy/user/ba ... exing.html
https://scipy-lectures.github.io/intro/ ... bject.html

Numpy und Matplotlib musst Du an Beispielen und mit der API-Doku lernen, es gibt für Numpy und Matplotlib keine richtig guten Bücher (wie es sie z.B. für Matlab gibt).
a fool with a tool is still a fool, www.magben.de, YouTube
lena_92
User
Beiträge: 28
Registriert: Donnerstag 24. Juli 2014, 15:00

@MagBen
Hey, danke dafür. :D Ich schaue mir mal die Sachen an. Ich glaube schon, dass ich so etwas suche. Habe in der Zwischenzeit dies gefunden:
http://stackoverflow.com/questions/1859 ... -in-python

Dies ist quasi was ich suche, allerdings bekomme ich die Zahl für die Zeilennummer # 3 nicht übergeben. Mit dieser Zahl würde ich dann komplett die Reihe "Mark", "66" übergeben wollen.

Danke
Lena


Edit:

SUPER, genau was ich gesucht habe. Ich kann deine Module super benutzten. Danken @ MagBen
Benutzeravatar
MagBen
User
Beiträge: 799
Registriert: Freitag 6. Juni 2014, 05:56
Wohnort: Bremen
Kontaktdaten:

lena_92 hat geschrieben:http://stackoverflow.com/questions/1859 ... -in-python

Dies ist quasi was ich suche, allerdings bekomme ich die Zahl für die Zeilennummer # 3 nicht übergeben. Mit dieser Zahl würde ich dann komplett die Reihe "Mark", "66" übergeben wollen.
Wo ist das Problem?

Code: Alles auswählen

table=[['John',  8, 'Student'   ],
       ['Paul', 22, 'Car Dealer'],
       ['Nick', 30, 'Doctor', 'this row is longer..','making 5'],
       ['Mark', 66, 'Retired'   ]]

print(table[3])
#['Mark', 66, 'Retired']
Das ist aber kein Numpy 2D-Array, das ist eine Standard-Python Liste von Listen. Du hast damit keinen direkten Zugriff auf Spalten wie mit Numpy. Du könntest diese Liste von Listen auch nicht in ein 2D-Array umwandeln, da ja nicht alle Zeilen gleich lang sind. Und wenn Sie es wären, dann könntest Du es trotzdem nicht in ein Numpy-Array umwandeln, weil unterschiedliche Datentypen (Strings und Zahlen) darin enthalten sind.
a fool with a tool is still a fool, www.magben.de, YouTube
Sirius3
User
Beiträge: 18335
Registriert: Sonntag 21. Oktober 2012, 17:20

@MagBen: Listen von Listen mit gleichvielen Elementen kann man natürlich immer in ein numpy-Array umwandeln, da ja alle den gleichen Datentyp object haben:

Code: Alles auswählen

table = numpy.array([['John',  8, 'Student'],
       ['Paul', 22, 'Car Dealer'],
       ['Nick', 30, 'Doctor'],
       ['Mark', 66, 'Retired']], dtype=object)

print(table[:,1])
# [8 22 30 66]
BlackJack

@Sirius3: Wobei bei solchen Daten vielleicht ein Record-Array mehr Sinn macht.

Code: Alles auswählen

In [24]: D
Out[24]: 
[['John', 8, 'Student'],
 ['Paul', 22, 'Car Dealer'],
 ['Nick', 30, 'Doctor'],
 ['Mark', 66, 'Retired']]

In [25]: R = numpy.rec.fromrecords(D, names=['name', 'age', 'profession'])

In [26]: R
Out[26]: 
rec.array([('John', 8, 'Student'), ('Paul', 22, 'Car Dealer'),
       ('Nick', 30, 'Doctor'), ('Mark', 66, 'Retired')], 
      dtype=[('name', 'S4'), ('age', '<i4'), ('profession', 'S10')])

In [27]: R.age
Out[27]: array([ 8, 22, 30, 66])

In [28]: R.age == 30
Out[28]: array([False, False,  True, False], dtype=bool)

In [29]: R[R.age == 30]
Out[29]: 
rec.array([('Nick', 30, 'Doctor')], 
      dtype=[('name', 'S4'), ('age', '<i4'), ('profession', 'S10')])
lena_92
User
Beiträge: 28
Registriert: Donnerstag 24. Juli 2014, 15:00

Kann mir jemand kurz die Bedeutung von [0,0] erklären? Welcher Index wir damit gesteuert und welche Funktion übernimmt dieser hier? Bei dem bearbeiten bekomme ich regelmäßig Fehlermeldungen.
MagBen hat geschrieben:

Code: Alles auswählen

 
# http://docs.scipy.org/doc/numpy/reference/routines.sort.html
row_index = np.argwhere(find_15)[0,0] # [0,0]: es koennte ja mehrere Fundstellen geben.
print(row_index)
# 2
Sirius3
User
Beiträge: 18335
Registriert: Sonntag 21. Oktober 2012, 17:20

@lena_92: wie lautet die Fehlermeldung/Traceback und der dazugehörige Code?
Benutzeravatar
MagBen
User
Beiträge: 799
Registriert: Freitag 6. Juni 2014, 05:56
Wohnort: Bremen
Kontaktdaten:

argwhere gibt die Indizes der Elemente != 0 als 2D-Array zurück:

Code: Alles auswählen

import numpy as np
print(repr(np.argwhere([False, False, True, False])))
# array([[2]], dtype=int64), 2D-Array: 1 x 1 Elemente

print(repr(np.argwhere([True, False, True, False])))
# array([[0],
#       [2]], dtype=int64), 2D-Array: 2 x 1 Elemente

print(repr(np.argwhere([False, False, False, False])))
# array([], shape=(0L, 1L), dtype=int64); 2D-Array: 0 x 1 Elemente
Wenn Du nun aber nur einen einzelnen Fund-Index haben willst, dann kannst Du mit [0,0] auf ein Element dieses 2D-Arrays zugreifen. Wenn aber alles False ist, dann bekommst Du ein leeres 2D-Array zurück und kannst dann nicht auf einen einzelnen Fund-Index zugreifen.
a fool with a tool is still a fool, www.magben.de, YouTube
lena_92
User
Beiträge: 28
Registriert: Donnerstag 24. Juli 2014, 15:00

Hey mein Fehler sieht so aus:

Traceback (most recent call last):
File "Test_2.py", line 60, in <module>
row_index = np.argwhere(find_15)[0,0] # [0,0]: es koennte ja mehrere Fundstellen geben.
IndexError: invalid index


Bei dem code habe ich nichts geändert. Ich lade nur eine externe Matrix 9x4.

Danke
Lena
Benutzeravatar
MagBen
User
Beiträge: 799
Registriert: Freitag 6. Juni 2014, 05:56
Wohnort: Bremen
Kontaktdaten:

lena_92 hat geschrieben:Bei dem code habe ich nichts geändert. Ich lade nur eine externe Matrix 9x4.
Du müsstest den Fall berücksichtigen, dass die geladenen Daten das Gesuchte nicht enthalten, dann ist wie oben beschrieben das Ergebnis von argwhere ein leeres Array.
a fool with a tool is still a fool, www.magben.de, YouTube
lena_92
User
Beiträge: 28
Registriert: Donnerstag 24. Juli 2014, 15:00

Meine geladene Datei / Matrix sieht wie folgt aus:

Code: Alles auswählen

 200323 -0.4600000E+02  0.2828137E+02  0.1375673E+03                                                
 200323 -0.7400000E+02  0.2693271E+02  0.7662270E+03                                                
 200369 -0.7100000E+02  0.2561206E+02  0.1298868E+03                                                
 200392 -0.2100000E+02  0.3730040E+02  0.7354466E+03                                                
 200415 -0.1500000E+02  0.2304675E+02  0.3222063E+03                                                
 200438 -0.6700000E+02  0.1376809E+02  0.1208661E+03                                                
 200461 -0.4600000E+02  0.1346544E+02  0.8995259E+03                                                
 200484 -0.3400000E+02  0.8716278E+02  0.7615856E+03                                                
 200507 -0.4800000E+02  0.7886013E+02  0.8682454E+03                                                
Mein Code sieht wie folgt aus:

Code: Alles auswählen

knoten_start = 200323
knoten_end = 200507

i = knoten_start
while (knoten_start <= i <= knoten_end):

	data_2d = np.loadtxt('Knotenpunkte_Koordinaten.txt')	
	search_string = i

	# Zugriff auf 2. Reihe
	row_2 = data_2d[1,:] # Kurzform: row_2 = data_2d[1]
	#print(row_2)
	# [ 6  7  8  9 10 11]


	# Zugriff auf 4. Spalte:
	column_4 = data_2d[:,0]
	#print(column_4)
	# [ 3  9 15 21]

	# Wo ist die 15?
	find_15 = column_4==search_string
	# Selbst beim Suchen in der ganzen Datei werden keine Lösungen ausgegeben.
             #find_15 = data_2d==search_string
	#print(find_15)
	# [False False  True False]

	 # http://docs.scipy.org/doc/numpy/reference/routines.sort.html
	row_index = np.argwhere(find_15)[0:0] # [0,0]: es koennte ja mehrere Fundstellen geben.
	print(row_index)
	# 2
	row_with_value15 = data_2d[row_index]
	#print(row_with_value15)
	# [12 13 14 15 16 17]

	# oder direkter:
	#print( data_2d[find_15,:])
	# [[12 13 14 15 16 17]]

	i = i + 23

Also, ich bekomme inzwischen leere Ergebnisse raus, was nach euren Hinweise ja heißt, dass dies Nummer nicht in der Textdatei enthalten sind. Ich habe nun beides hier rein kopiert. Liegt es an den negativen Zahlen in Spalte 2? Was gibt es für andere Möglichkeiten?
Grüße
Lena
lena_92
User
Beiträge: 28
Registriert: Donnerstag 24. Juli 2014, 15:00

Ich habe den Fehler gefunden:

Es lag tatsächlich an dem vorher besprochenen Index.

Die Korrektur ist.

Code: Alles auswählen

row_index = np.argwhere(find_15)[: ,]
Vielen Dank für die Hilfe
Lena
BlackJack

@lena_92: Die Namen und Kommentare passen ja so was von gar nicht zu dem was der Quelltext macht. Das solltest Du dringend ändern.

Anstelle der ``while``-Schleife würde man eine ``for``-Schleife über ein `xrange()`-Objekt verwenden (`range()` in Python 3). Um die Bedingung braucht man auch keine Klammern zu setzen.

Das Du leere Ergebnisse bekommst liegt schlicht daran das nicht alle `i`-Werte nach denen Du suchst, in den Daten vorkommen. Das ist doch offensichtlich. Du suchst im ersten Durchgang nach 200323 und im zweiten dann nach 200346 → diese Zahl ist in der ersten Spalte offensichtlich nicht enthalten.

Die ”Korrektur” ist Unsinn, das ergibt nur wieder das Array welches von `argwhere()` sowieso schon geliefert wird. Der Indexzugriff hat also auf das Ergebnis keinen Effekt und kann deshalb weg gelassen werden. Wenn Du alle Fundstellen haben möchtest ist `argwhere()` auch etwas umständlich. Da kann man dann auch gleich ein Array mit Wahrheitswerten als Index verwenden.

Was soll denn das eigentliche Ziel dieser Operation sein? Was hast Du da an Daten und wie soll das Ergebnis aussehen?
Benutzeravatar
MagBen
User
Beiträge: 799
Registriert: Freitag 6. Juni 2014, 05:56
Wohnort: Bremen
Kontaktdaten:

in Zeile 29 muss es [0,0] statt [0:0] heißen

Wenn Du Code kopierst und veränderst, dann solltest Du alle Kommentare, die nicht mehr passen, unbedingt löschen.
Die Datei musst Du nicht jedes mal neu laden, einmal reicht.
Deine while-Schleife kann klarer mit einer for-Schleife realisiert werden.

So sieht das ganze etwas hübscher aus:

Code: Alles auswählen

import numpy as np

data_2d = np.loadtxt('Knotenpunkte_Koordinaten.txt')   

knoten_start = 200323
knoten_end = 200507
for i in range(knoten_start, knoten_end+1, 23):
        column_1 = data_2d[:,0]
        search_string_indexes = np.argwhere(column_1==i)
        
        for j in range(search_string_indexes.shape[0]):
            row_index = search_string_indexes[j,0]
            row_with_search_value = data_2d[row_index]
            print((row_index, row_with_search_value))
a fool with a tool is still a fool, www.magben.de, YouTube
lena_92
User
Beiträge: 28
Registriert: Donnerstag 24. Juli 2014, 15:00

Das Du leere Ergebnisse bekommst liegt schlicht daran das nicht alle `i`-Werte nach denen Du suchst, in den Daten vorkommen. Das ist doch offensichtlich. Du suchst im ersten Durchgang nach 200323 und im zweiten dann nach 200346 → diese Zahl ist in der ersten Spalte offensichtlich nicht enthalten.
Sorry, da ist mir ein Fehler unterlaufen. Der zweite Eintrag muss natürlich eine 200346 sein.

Das mit der for Schleife nehme mich auf und werde mich damit beschäftigen. Danke für den Hinweis.
Ich werde versuchen die Sachen aufzunehmen - leider kenn ich mich noch kaum aus.

Trotzdem danke!
BlackJack

@lena_92: Noch mal die Frage: Was sind das für Daten, wie sehen die aus, was soll als Ergebnis heraus kommen. Denn wenn die Nummern alle in der ersten Spalte vorkommen und die auch nur aus diesen Nummern besteht, und das auch noch in aufsteigender Reihenfolge, dann ist diese ganze Suchaktion völliger Unsinn, weil man dann einfach die Zeilen in einer Schleife durchgehen kann.

Sollten noch andere Nummern in der ersten Spalte vorkommen, dann kann man die gewünschten einfacher ausfiltern als da nach jeder einzelnen linear zu suchen. Und sollten die nicht in aufsteigender Reihenfolge sein, wäre sortieren effizienter als nach jeder einzeln zu suchen.

Wenn man mit Numpy-Arrays arbeitet ist jede Schleife in Python-Code etwas was man begründen können sollte, warum es keine Lösung gibt, welche die internen Schleifen in den Numpy-Typen und -Funktionen verwenden. Denn genau wegen denen verwendet man ja eigentlich Numpy-Arrays statt Python's Listentyp.
Antworten