Seite 1 von 2

csv einlesen in array of tuples und sortieren nach tupel-Element

Verfasst: Samstag 17. Oktober 2020, 20:47
von Krischu
Ich habe folgenden Code (python 3) jupyter notebook:

Code: Alles auswählen

import numpy as np
np.set_printoptions(precision=3)
data = [(1,2,3), (7,8,9), (4,5,6)]
spulen=np.genfromtxt(r'neue_messung.csv', delimiter=',',dtype="i2,f4,f4")

data.sort(key=lambda tup: tup[1])  # sorts in place

spulen.sort(key=lambda tup: tup[1]) 

print (spulen)
print(data)

--------------------

[(52, 872.72, 12.66) ( 2, 883.16, 12.46) (35, 881.2 , 12.5 )]
[(1, 2, 3), (4, 5, 6), (7, 8, 9)]

Mich wundert, warum nach dem Einlesen in np die Tupel nicht durch Komma getrennt sind. Zum Vergleich habe ich das mal mit data gemacht.
neue_messung.csv:

Code: Alles auswählen

52,872.72,12.66
2,883.16,12.46
35,881.20,12.50

Re: csv einlesen in array of tuples und sortieren nach tupel-Element

Verfasst: Samstag 17. Oktober 2020, 20:55
von Sirius3
Die print-Ausgabe ist ja nur für Debuggingzwecke, da kann jede Klasse das so machen, wie es will, und numpy spart sich die Kommas bei dieser Ausgabe. Das sind auch keine Tuple.
Für strukturierte Daten nimmt man heutzutage üblicherweise pandas.

Re: csv einlesen in array of tuples und sortieren nach tupel-Element

Verfasst: Samstag 17. Oktober 2020, 21:25
von Krischu
Sirius3 hat geschrieben: Samstag 17. Oktober 2020, 20:55 Die print-Ausgabe ist ja nur für Debuggingzwecke, da kann jede Klasse das so machen, wie es will, und numpy spart sich die Kommas bei dieser Ausgabe. Das sind auch keine Tuple.
Für strukturierte Daten nimmt man heutzutage üblicherweise pandas.
Ich hatte vergessen, den Fehler zu markieren. spulen und data sind unterschiedlliche Datentypen, denn:

-

Code: Alles auswählen

--------------------------------------------------------------------------
TypeError                                 Traceback (most recent call last)
<ipython-input-26-7cc5ab6b07fa> in <module>
      6 spulen=np.genfromtxt(r'neue_messung.csv', delimiter=',',dtype="i2,f4,f4")
      7 
----> 8 spulen.sort(key=lambda tup: tup[1])
      9 
     10 data.sort(key=lambda tup: tup[1])  # sorts in place

TypeError: 'key' is an invalid keyword argument for sort()
Habe das mal mit pandas gemacht, aber da bekomme ich keine so klaren Datentypen zurück.

Code: Alles auswählen

import pandas as pd

df = pd.read_csv('neue_mesung.csv',header=None)
print(df)

----------------
     0       1      2
0   52  872.72  12.66
1    2  883.16  12.46
2   35  881.20  12.50

Sieht ja hübsch formatiert aus, aber ich brauche ein Array von Tupeln.

OK, ich muß df nach numpy convertieren.

Re: csv einlesen in array of tuples und sortieren nach tupel-Element

Verfasst: Samstag 17. Oktober 2020, 22:11
von Krischu
Aber df.to_numpy funktioniert nicht. (!?)

Code: Alles auswählen

import pandas as pd

import numpy as np
df = pd.read_csv('neue_messung.csv',header=None)
spulen=df.to_numpy()


---------------------------------------------------------------------------
AttributeError                            Traceback (most recent call last)
<ipython-input-14-b5f0b33f33d3> in <module>
      4 df = pd.read_csv('neue_mesung.csv',header=None)
      5 
----> 6 spulen=df.to_numpy()
      7 

~/anaconda3/lib/python3.7/site-packages/pandas/core/generic.py in __getattr__(self, name)
   4374             if self._info_axis._can_hold_identifiers_and_holds_name(name):
   4375                 return self[name]
-> 4376             return object.__getattribute__(self, name)
   4377 
   4378     def __setattr__(self, name, value):

AttributeError: 'DataFrame' object has no attribute 'to_numpy'


Re: csv einlesen in array of tuples und sortieren nach tupel-Element

Verfasst: Samstag 17. Oktober 2020, 22:26
von Krischu
Habe ein Problem mit meiner Installation (macOS) anaconda3. In Jupyterlab funktioniert das Beispiel. Rufe ich jupyter notebook aus dem Terminal auf, so geht's nicht.

Re: csv einlesen in array of tuples und sortieren nach tupel-Element

Verfasst: Samstag 17. Oktober 2020, 22:34
von sparrow
Was gefällt dir denn nicht daran, die Daten mit Numpy einzulesen?

Vielleicht solltest du mal erklären, was du vor hast, bevor du zu den falschen Werkzeugen greifst.

Re: csv einlesen in array of tuples und sortieren nach tupel-Element

Verfasst: Sonntag 18. Oktober 2020, 06:48
von Krischu
sparrow hat geschrieben: Samstag 17. Oktober 2020, 22:34 Was gefällt dir denn nicht daran, die Daten mit Numpy einzulesen?

Vielleicht solltest du mal erklären, was du vor hast, bevor du zu den falschen Werkzeugen greifst.
Ursprünglich - siehe mein gepostetes Beispiel - wollte ich es ja mit numpy machen (np.getfromtxt()).
Aber Sirius3 sagte ja, "strukturierte Daten verarbeite man heutzutage mit pandas".

Meine ursprüngliche Aufgabe (Ziel) ist schon in meinem ersten Post enthalten:

Ich habe eine Meßreihe von Daten:

Code: Alles auswählen

Integer ID des Gegenstandes,  Float Wert1 ,  Float Wert2
in einer CSV-Datei.

Die will ich einlesen und nach "Wert1" numerisch sortieren.

Eigentlich ein Array von Tupeln. So wie in "data".
Ich fand in einem stackoverflow-Beispiel dieses "sorts in place"-Beispiel:

Code: Alles auswählen

data.sort(key=lambda tup: tup[1])  # sorts in place
Sehe ich mir das eingelesene Array "spulen" an, so sieht das anders aus: Tupel, ohne Komma.
Sirius3 meinte, es sei nur eine Sache der Darstellung.
Wenn ich aber "spulen" genauso dem sort unterwerfe, gibt es einen Fehler. (siehe Post)

Code: Alles auswählen

data = [(1,2,3), (7,8,9), (4,5,6)]
spulen=np.genfromtxt(r'neue_messung.csv', delimiter=',',dtype="i2,f4,f4")

data.sort(key=lambda tup: tup[1])  # sorts in place

spulen.sort(key=lambda tup: tup[1]) 

Später sollen die Tupel noch erweitert werden um Verküpfungsergebnisse aus Spalten 2 und 3, aber das kommt später.

Re: csv einlesen in array of tuples und sortieren nach tupel-Element

Verfasst: Sonntag 18. Oktober 2020, 07:25
von sparrow
Wenn Tupel erweitert werden sollen, dann möchtest du keine Tupel sondern Listen - oder etwas anderes, das im Gegensatz zu Tupeln veränderlich ist.

Die Schwierigkeit ist, dass man nicht einschätzen kann, welche Erfshrung du hast und ob du weißt was man wofür benutzt und warum.
Du hsst ein Problem, denkst, du hast eine Lösung, damit kommst du ins Schleudern und fragst elra das liegt.
Nicht selten liegt das daran, dass die Lösung nicht zum Problem passt.
Magst du mal dein Ursprungsproblem schildern? Und warum du Numpy brauchst?

Re: csv einlesen in array of tuples und sortieren nach tupel-Element

Verfasst: Sonntag 18. Oktober 2020, 08:11
von Krischu
Aber ich glaube, ich weiß jetzt, wo's lang geht:

Ich muß nd_array in list umwandeln.

Habe ich mein Ziel, Aufgabe, Vorhaben, nicht schon ausreichend beschrieben? Mal ganz ohne Verwendung von Python Objektbezeichnungen:

1. Die CSV-Datei soll eingelesen werden (3 Spalten).
2. Es werden Verknüpfungen zwischen Spaltenelementen gebildet (Funktion) und das Ergebnis in zwei weiteren Spalten hinzugefügt.
3. Die Krönung wäre, das noch als Excel-Datei herauszuschreiben.

(Anm: wie macht man hier mit dem Editor eine schöne numerierte Liste?)

Aber Letzteres ist kein Muß.

Also, so geht's:

Code: Alles auswählen

import numpy as np
np.set_printoptions(precision=3)
data = [(1,2,3), (7,8,6), (4,5,6)]


spulen=np.genfromtxt(r'neue_mesung.csv', delimiter=',',dtype=[('i4'),('f8'),('f8')]).tolist()

print(type(spulen))


spulen.sort(key=lambda tup: tup[1]) # sortiert in situ

print(spulen)

-------

<class 'list'>
[(81, 867.38, 12.91), (52, 872.72, 12.66), (40, 872.87, 12.6)]

Re: csv einlesen in array of tuples und sortieren nach tupel-Element

Verfasst: Sonntag 18. Oktober 2020, 09:42
von sparrow
Wenn du keine mehrdimensionalen Arrays brauchst, mit denen du rechnest, ist Pandas das richtige Werkzeug.
Deshalb die Frage nach dem "Großen Ganzen"

Re: csv einlesen in array of tuples und sortieren nach tupel-Element

Verfasst: Sonntag 18. Oktober 2020, 10:56
von Sirius3
@Krishu: ich bin ja nicht seit gestern hier.
1. Die CSV-Datei soll eingelesen werden (3 Spalten).
> Da gibt es was bei Pandas.
2. Es werden Verknüpfungen zwischen Spaltenelementen gebildet (Funktion) und das Ergebnis in zwei weiteren Spalten hinzugefügt.
> Das ist DER Anwendungsfall von pandas.
3. Die Krönung wäre, das noch als Excel-Datei herauszuschreiben.
> das bringt Pandas schon mit.
Daher mein Tipp:
arbeite dich in Pandas ein und frage dich: wie kann ich dies oder dies Problem mit Pandas lösen.

Re: csv einlesen in array of tuples und sortieren nach tupel-Element

Verfasst: Sonntag 18. Oktober 2020, 11:15
von Krischu
Sirius3 hat geschrieben: Sonntag 18. Oktober 2020, 10:56 @Krishu: ich bin ja nicht seit gestern hier.
1. Die CSV-Datei soll eingelesen werden (3 Spalten).
> Da gibt es was bei Pandas.
2. Es werden Verknüpfungen zwischen Spaltenelementen gebildet (Funktion) und das Ergebnis in zwei weiteren Spalten hinzugefügt.
> Das ist DER Anwendungsfall von pandas.
3. Die Krönung wäre, das noch als Excel-Datei herauszuschreiben.
> das bringt Pandas schon mit.
Daher mein Tipp:
arbeite dich in Pandas ein und frage dich: wie kann ich dies oder dies Problem mit Pandas lösen.
"..nicht seit gestern" - das sehe ich wohl an der Zahl Deiner Beiträge.

Tja, dann wohl pandas und bis zur nächsten "pandas-Frage" :) Schönen Sonntag,

Christoph

Re: csv einlesen in array of tuples und sortieren nach tupel-Element

Verfasst: Sonntag 18. Oktober 2020, 17:25
von Krischu
Jetzt komme ich doch noch mit meiner ersten pandas-Frage:

Hier ist der code, der soweit läuft und ich habe schon mal die Verknüpfung definiert, die in Spalte dL eingefügt werden soll:
(habe mal das csv-Lesen ausgeklammert)

Code: Alles auswählen

import pandas as pd

def fun(col1,col2):
    return 2*(col2-col1)/(col2+col1)
 
#df = pd.read_csv('neue_messung.csv',names=['ID','L','R'],header=None)
data=[(52,872.72,12.66),
(2,883.16,12.46),
(35,881.20,12.50),
(47,881.92,12.50),
(19,874.97,12.71)]
df = pd.DataFrame(data,columns=['ID','L','R'])
print(df)
df['dL'] = 0
df['dR'] = 0

sorted_df = df.sort_values(by='L')
print(fun(sorted_df['L'][1],sorted_df['L'][0]))
sorted_df


----------------------------------------------
   ID       L      R
0  52  872.72  12.66
1   2  883.16  12.46
2  35  881.20  12.50
3  47  881.92  12.50
4  19  874.97  12.71
-0.011891473221404584

	ID 	L 	R 	dL 	dR
0 	52 	872.72 	12.66 	0 	0
4 	19 	874.97 	12.71 	0 	0
2 	35 	881.20 	12.50 	0 	0
3 	47 	881.92 	12.50 	0 	0
1 	2 	883.16 	12.46 	0 	0

Meine Pandasfrage: wie addressiere ich - wie in diesem Beispiel - Spalte 'L'(i) und Spalte 'L'(i-1) bzw. weise der Spalte die Funktion zu?
dL[0] bliebe 0 bzw. leer

Re: csv einlesen in array of tuples und sortieren nach tupel-Element

Verfasst: Sonntag 18. Oktober 2020, 18:12
von Sirius3
Du suchst nach `shift`:

Code: Alles auswählen

df['dL'] = fun(df['L'], df['L'].shift(1))

Re: csv einlesen in array of tuples und sortieren nach tupel-Element

Verfasst: Sonntag 18. Oktober 2020, 18:30
von Krischu
Aha. Danke!

Re: csv einlesen in array of tuples und sortieren nach tupel-Element

Verfasst: Montag 19. Oktober 2020, 07:00
von Krischu
Nächste kleine Hürde:

Code: Alles auswählen

import pandas as pd

def fun(col1,col2):
    if  col1 != 0 and  col2 != 0 and not col1.empty and not col2.empty :
        return 2*(col2-col1)/(col2+col1)
    else:
        return Nan
-------------------

/opt/anaconda3/lib/python3.7/site-packages/pandas/core/generic.py in __nonzero__(self)
   1477     def __nonzero__(self):
   1478         raise ValueError(
-> 1479             f"The truth value of a {type(self).__name__} is ambiguous. "
   1480             "Use a.empty, a.bool(), a.item(), a.any() or a.all()."
   1481         )

ValueError: The truth value of a Series is ambiguous. Use a.empty, a.bool(), a.item(), a.any() or a.all().
       

Re: csv einlesen in array of tuples und sortieren nach tupel-Element

Verfasst: Montag 19. Oktober 2020, 07:18
von snafu
Ungetestet:

Code: Alles auswählen

def fun(col1,col2):
    if not col1.any() and not col2.any():
        return NaN
    return 2 * (col2 - col1) / (col2 + col1)
empty wird übrigens auch abgedeckt, da any() False liefert, wenn kein Element vorhanden ist.

Wie du siehst, habe ich die Logik umgedreht, weil es meist einfacher ist, erstmal die möglichen Fehlerfälle zu behandeln und dann die eigentliche Formel anzugeben. Ein explizites else wird nicht mehr benötigt, wenn man schon vorher mit return ausgestiegen ist.

Re: csv einlesen in array of tuples und sortieren nach tupel-Element

Verfasst: Montag 19. Oktober 2020, 07:45
von Sirius3
@Krischu: das Problem ist, dass Du mit Vektoren rechnest, also ist snafus Lösung keine.
Und Du mußt gar nichts machen, weil bei 0 / 0 als Ergebnis schon 'NaN' liefert.

Richtig ist also:

Code: Alles auswählen

def fun(col1, col2):
    return 2 * (col2 - col1) / (col2 + col1)

Re: csv einlesen in array of tuples und sortieren nach tupel-Element

Verfasst: Montag 19. Oktober 2020, 08:45
von Krischu
Danke. Sieht elegant aus.

Bin jetzt an diesem Punkt: (Ich frage mich, was macht mehr Spaß: OfficeCalc/Excel zu lernen oder Python/Pandas zu programmieren? - ich finde, Letzteres):

Code: Alles auswählen

import pandas as pd

def fun(col1,col2):
        return abs(2*(col2-col1)/(col2+col1))*100.
    
def paar(col1,col2):
    if col1  < 0.02 and col2  < 2 :
        return "P"
    else:
        return "-"
    
df = pd.read_csv('neue_messung.csv',names=['ID','L [µH]','R [Ω]'],header=None)

#print(df)
df['dL [%]'] = 0
df['dR [%]'] = 0
df['Paar']=""
#
# ds = sorted df
ds = df.sort_values(by='L [µH]')
ds['dL [%]']=fun(ds['L [µH]'],ds['L [µH]'].shift(1))
ds['dR [%]']=fun(ds['R [Ω]'],ds['R [Ω]'].shift(1))
ds['dL [%]']=ds['dL [%]'].apply(lambda x:round(x,2))
ds['dR [%]']=ds['dR [%]'].apply(lambda x:round(x,2))
ds['Paar']=paar(ds['dL [%]'],ds['dR [%]'])
ds
Aber es kracht mal wieder:

Code: Alles auswählen

---------------------------------------------------------------------------
ValueError                                Traceback (most recent call last)
<ipython-input-94-56daec2d8e74> in <module>
     23 ds['dL [%]']=ds['dL [%]'].apply(lambda x:round(x,2))
     24 ds['dR [%]']=ds['dR [%]'].apply(lambda x:round(x,2))
---> 25 ds['Paar']=paar(ds['dL [%]'],ds['dR [%]'])
     26 ds

<ipython-input-94-56daec2d8e74> in paar(col1, col2)
      5 
      6 def paar(col1,col2):
----> 7     if col1  < 0.02 and col2  < 2 :
      8         return "P"
      9     else:

/opt/anaconda3/lib/python3.7/site-packages/pandas/core/generic.py in __nonzero__(self)
   1477     def __nonzero__(self):
   1478         raise ValueError(
-> 1479             f"The truth value of a {type(self).__name__} is ambiguous. "
   1480             "Use a.empty, a.bool(), a.item(), a.any() or a.all()."
   1481         )

ValueError: The truth value of a Series is ambiguous. Use a.empty, a.bool(), a.item(), a.any() or a.all().

Übrigens, Nebenfrage:

An einem Punkt beim Erzeugen der dL/dR-Spalten mußte ich die Funktion umstellen, so, daß sie % zurückgibt. Ich hätte aber lieber den wirklichen Quotienten gehabt. Nur wegen der Formatierung sah ich mich gezwungen, den Wert mit 100 zu multiplizieren. Kann man - das geht sicher - die Ausgabe in der Spalte einer Formatierung unterziehen, derart, daß der eigentlich hinterlegte Wert in % ausgegeben wird?

Re: csv einlesen in array of tuples und sortieren nach tupel-Element

Verfasst: Montag 19. Oktober 2020, 09:12
von Sirius3
Weil ich auch nur google benutzen kann, hier der Link zur Nebenfrage: https://stackoverflow.com/questions/239 ... r-36175424
Während einer Rechnung rundet man normalerweise nicht, sondern erst bei der Ausgabe.

Du mußt noch lernen, wie man mit Pandas arbeitet. Dazu hilft das Pandas-Tutorial.

Code: Alles auswählen

def paar(row):
    return "P" if row["L"] < 0.2 and row["R"] < 2 else "-"

ds['Paar'] = ds.apply(paar, axis=1)