Geister-Array ?!?

mit matplotlib, NumPy, pandas, SciPy, SymPy und weiteren mathematischen Programmbibliotheken.
Antworten
Karlirex
User
Beiträge: 126
Registriert: Dienstag 18. August 2020, 18:27

Hallo Leute,

ich gebe Arrays per Dateieinlesung vor und möchte diese dann mit einem bestimmten Start-Array zusammenzufügen.
Bei der Vorgabe aus einer Datei funktioniert dies. Bei drei Dateien erhielt ich "ValueError: all the input arrays must have same number of dimensions, but the array at index 0 has 1 dimension(s) and the array at index 1 has 0 dimension(s)" als Fehlermeldung.

Bei der Fehlersuche fiel mir dann auf, dass ich ein Array zur Verfügung habe, welches zu dem Zeitpunkt nicht existieren sollte. Und dann auch noch "falsch" ist, da diese Datei so zu dem Punkt nicht existiert. Sozusagen ein Geister-Array.

Wieso ist es dort?

So gibts die Fehlermeldung:

Code: Alles auswählen

########################## Daten einlesen ################################

data_sorbitol = np.genfromtxt("Sorbitol.csv", delimiter = ";")
data_isosorbid = np.genfromtxt("Isosorbid.csv", delimiter = ";")
x, name, conc_sorbitol = data_sorbitol.T
x, name, conc_isosorbid = data_isosorbid.T

########################## Startvorgabe #####################################

m_sorbitol = 2000
m_ansatz = 22.4
start_sorbitol = np.array([m_sorbitol / m_ansatz])
start_isosorbid = np.array([0])

########################## Zusammenschluss ###################################

conc_sorbitol = np.array([conc_sorbitol])
conc_isosorbid = np.array([conc_isosorbid])
sorbitol_conc = np.concatenate((start_sorbitol, conc_sorbitol))
isosorbid_conc = np.concatenate((start_isosorbid, conc_isosorbid))

print(isosorbid_conc)
print(sorbitol_conc)
print(conc_isosorbid)
print(start_isosorbid)
print(start_isosorbid.shape)
print(conc_sorbitol.shape)
print(conc_isosorbid.shape)
print(isosorbid_conc.shape)
print(sorbitol_conc.shape)
So erhalte ich das "isosorbid_conc"-Array obwohl es nicht existieren sollte:

Code: Alles auswählen

########################## Daten einlesen ################################

data_sorbitol = np.genfromtxt("Sorbitol.csv", delimiter = ";")
data_isosorbid = np.genfromtxt("Isosorbid.csv", delimiter = ";")
x, name, conc_sorbitol = data_sorbitol.T
x, name, conc_isosorbid = data_isosorbid.T

########################## Startvorgabe #####################################

m_sorbitol = 2000
m_ansatz = 22.4
start_sorbitol = np.array([m_sorbitol / m_ansatz])
start_isosorbid = np.array([0])

########################## Zusammenschluss ###################################

conc_sorbitol = np.array([conc_sorbitol])
conc_isosorbid = np.array([conc_isosorbid])
#sorbitol_conc = np.concatenate((start_sorbitol, conc_sorbitol))
#isosorbid_conc = np.concatenate((start_isosorbid, conc_isosorbid))

print(isosorbid_conc)
print(sorbitol_conc)
print(conc_isosorbid)
print(start_isosorbid)
print(start_isosorbid.shape)
print(conc_sorbitol.shape)
print(conc_isosorbid.shape)
print(isosorbid_conc.shape)
print(sorbitol_conc.shape)
Sirius3
User
Beiträge: 18219
Registriert: Sonntag 21. Oktober 2012, 17:20

Wenn Du die Daten entpacken willst, dann benutze unpack:

Code: Alles auswählen

_, name, conc_sorbitol = np.genfromtxt("Sorbitol.csv", delimiter=";", unpack=True)
Wie startest Du den Code? Doch nicht mit diesem Jupyter-Zeugs. Das benutzt quasi nur globale Variablen, was das finden von Fehlern praktisch unmöglich macht.
Da muß man sehr sorgfältig programmieren, weshalb ich das für Anfänger nicht empfehlen würde.

Bei concatenate muß man darauf achten, über die richtigen Dimensionen zusammenzufügen.
Welche Shapes haben denn die beiden Arrays?
Irgendwie habe ich das Gefühl, Dir das alles schonmal geschrieben zu haben.
Karlirex
User
Beiträge: 126
Registriert: Dienstag 18. August 2020, 18:27

@sirius3 doch genau mit dem Jupyter-Zeugs, da ich nicht nur an einem Ort programmiere und so immer die aktuellste Version auf den 7 Rechnern habe :D

Ich habe mittlerweile mein Problem mit .flatten() gelöst, da es bei einer Datei wohl als Liste und bei 3 als passendes Array behandelt wurde.

Was genau bewirkt mir denn das unpack?

Ich habe in den letzten Tagen öfter hier Fragen gestellt. Leider irgendwie immer neue und andere, obowhl das Gesamtproblem noch das Gleiche ist :/
Ich müsste vllt mehr die ganzen Befehle kennenlernen, aber da ich Python nur nutze weil eine Projektarbeit dies als Auswertevorgabe hat, soll es erstmal nur funktionieren.

Danke für deine Hilfe und Geduld mit mir ;)
Sirius3
User
Beiträge: 18219
Registriert: Sonntag 21. Oktober 2012, 17:20

Statt den einen unnötigen Umweg mit weiterem Code wieder auf den richtigen Weg zu bringen, ist die Lösung weniger, statt mehr:

Code: Alles auswählen

# Startvorgaben
sorbitol = 2000
ansatz = 22.4
start_sorbitol = np.array([sorbitol / ansatz])
start_isosorbidtol = np.array([0])

_, _, concentration_sorbitol = np.genfromtxt("Sorbitol.csv", delimiter=";", unpack=True)
_, name, concentration_isosorbitol = np.genfromtxt("Isosorbitol.csv", delimiter=";", unpack=True)

concentration_sorbitol = np.concatenate([start_sorbitol, concentration_sorbitol])
concentration_isosorbitol = np.concatenate([start_isosorbitol, concentration_isosorbitol])
Das weniger bezieht sich aber nicht auf Variablennamen: vermeide unsinnige Abkürzungen, weil Du damit zwei Probleme hast, Du mußt Dich beim Lesen daran erinnern, was die Abkürzung ausgeschrieben bedeutet und beim Schreiben, wie Du nun das Wort abgekürzt hast
Karlirex
User
Beiträge: 126
Registriert: Dienstag 18. August 2020, 18:27

@Sirius3 ich habe mir deinen Vorschlag einmal genommen und getestet.
Bei einer Dateieinlesung, welche sich in der CSV befindet(1 Zeile) funktioniert es nicht(wie gestern ohne flatten).
Bei drei Dateien, welche der CSV-Datei 3 Zeilen gibt, läuft dein Vorschlag auch. Mit flatten aber eben Reibungslos in beiden Fällen.

So läuft es eben. Vllt habe ich aber auch irgendwo anders den Fehler wieder drin.

Code: Alles auswählen

def write_all(file):
    data = pd.read_csv('./Test/' + file, sep='\s+' , decimal = ',', names = ['ID', 'Name', 'R.Time', 'Area', 'Height', 'Conc.','Curve', '3rd', '2nd', '1st', 'Constant', 'Area Ratio', 'Height Ratio', 'Conc. %', 'Norm Conc.'])
    
    name = np.array(data['Name'])
    conc = np.array(data['Conc.'])
    
    info_df = {"Name": name, "Conc. mg/g": conc}
    df = pd.DataFrame(data = info_df)
    
    select_sorbitol = df.loc[df['Name'] == 'Sorbitol']
    select_isosorbid = df.loc[df['Name'] == 'Isosorbitol']
    
    select_sorbitol.to_csv("Sorbitol.csv", mode = "a", header = False, sep = ";")
    select_isosorbid.to_csv("Isosorbitol.csv", mode = "a", header = False, sep = ";")
    
  ###Eingabe der zuverwendenden Dateien#####  
  
    i = 0

while True:
    i = i + 1
    file = input()
    if not file:
        break
    write_all(file)
    
########################## Daten einlesen ################################

data_sorbitol = np.genfromtxt("Sorbitol.csv", delimiter = ";")
data_isosorbid = np.genfromtxt("Isosorbid.csv", delimiter = ";")
x, name, conc_sorbitol = data_sorbitol.T
x, name, conc_isosorbid = data_isosorbid.T

########################## Startvorgabe #####################################

m_sorbitol = 2000
m_ansatz = 22.4
start_sorbitol = np.array([m_sorbitol / m_ansatz])
start_isosorbid = np.array([0])

########################## Zusammenschluss ###################################


conc_sorbitol = np.array([conc_sorbitol]).flatten()
conc_isosorbid = np.array([conc_isosorbid]).flatten()

sorbitol_conc = np.concatenate((start_sorbitol, conc_sorbitol))
isosorbid_conc = np.concatenate((start_isosorbid, conc_isosorbid))
Sirius3
User
Beiträge: 18219
Registriert: Sonntag 21. Oktober 2012, 17:20

Stimmt, bei nur einer Zeile verhält sich numpy nicht ganz konsistent.

Code: Alles auswählen

# Startvorgaben
sorbitol = 2000
ansatz = 22.4
start_sorbitol = np.array([sorbitol / ansatz])
start_isosorbidtol = np.array([0])

_, _, concentration_sorbitol = np.genfromtxt("Sorbitol.csv", delimiter=";", unpack=True)
_, name, concentration_isosorbitol = np.genfromtxt("Isosorbitol.csv", delimiter=";", unpack=True)

concentration_sorbitol = np.concatenate([start_sorbitol, concentration_sorbitol.ravel()])
concentration_isosorbitol = np.concatenate([start_isosorbitol, concentration_isosorbitol.ravel()])
Weiter oben hast du einen Einrückfehler. Statt einer while-Schleife benutzt man eine for-Schleife.

Code: Alles auswählen

from itertools import count

for nr in count(1):
    filename = input()
    if not filename:
        break
    writeall(filename)
Karlirex
User
Beiträge: 126
Registriert: Dienstag 18. August 2020, 18:27

Was genau ist der Unterschied bei ravel zu flatten?
Und weshalb benutzt man statt der while-Schleife die for-Schleife? Es funktioniert ja beides :'D

Danke @sirius3 für deine Hilfe, habe es jetzt mal so übernommen ;)
Sirius3
User
Beiträge: 18219
Registriert: Sonntag 21. Oktober 2012, 17:20

flatten macht eine Kopie der Daten, die du nicht brauchst. Bei for ist klar was passiert, bei while muss man erst suchen, wie sich die Nummer verändert.
Antworten