2016-09-14 6 views
2

Ich habe eine CSV mit zwei Trennzeichen (;) und (,) sieht das so aus:CSV-Import mit zwei Trennzeichen Pandas

vin;vorgangid;eventkm;D_8_lamsoni_w_time;D_8_lamsoni_w_value 
V345578;295234545;13;-1000.0,-980.0;7.9921875,11.984375 
V346670;329781064;13;-960.0,-940.0;7.9921875,11.984375 

ich es in einen Pandas Datenrahmen importieren möchten, mit dem (;) als Trennzeichen und (,) als Trennzeichen für list oder mit float als Datentyp. Bisher benutze ich diese Methode, aber ich bin mir sicher, dass es da draußen etwas einfacher gibt.

aa=0; 
csv_import=pd.read_csv(folder+FileName, ';') 
for col in csv_import.columns: 
aa=aa+1 
if type(csv_import[col][0])== str and aa>3: 
    # string to list of strings 
    csv_import[col]=csv_import[col].apply(lambda x:x.split(',')) 
    # make the list of stings into a list of floats 
    csv_import[col]=csv_import[col].apply(lambda x: [float(y) for y in x]) 

Antwort

3

Asides fr om die anderen feinen Antworten hier, die mehr Pandas-spezifische sind, sollte beachtet werden, dass Python selbst ziemlich mächtig ist, wenn es um die String-Verarbeitung kommt. Sie können nur das Ergebnis platzieren ';' mit ',' in einem StringIO Objekt zu ersetzen, und die Arbeit normalerweise von dort:

In [8]: import pandas as pd 

In [9]: from cStringIO import StringIO 

In [10]: pd.read_csv(StringIO(''.join(l.replace(';', ',') for l in open('stuff.csv')))) 
Out[10]: 
        vin vorgangid eventkm D_8_lamsoni_w_time \ 
V345578 295234545 13 -1000.0 -980.0   7.992188 
V346670 329781064 13  -960.0 -940.0   7.992188 

        D_8_lamsoni_w_value 
V345578 295234545   11.984375 
V346670 329781064   11.984375 
+0

Interessanter Ansatz, wie funktioniert das in Python 3.5? importieren io pd.read_csv (io ('' .join (l.replace (';', ',')) für l in open ('stuff.csv')))) funktioniert nicht – valenzio

+0

@valenzio Ich habe gerade dies auf 3.5.2 überprüft, und es ist genauso. –

+0

Ich bekomme die Massage, kein Modul namens 'cStringIO' muss ich dieses Modul über Pip installieren, hatte ich das Gefühl, es kommt mit Python – valenzio

3

erste CSV Lese ; als Trennzeichen verwenden:

df = pd.read_csv(filename, sep=';') 

UPDATE:

In [67]: num_cols = df.columns.difference(['vin','vorgangid','eventkm']) 

In [68]: num_cols 
Out[68]: Index(['D_8_lamsoni_w_time', 'D_8_lamsoni_w_value'], dtype='object') 

In [69]: df[num_cols] = (df[num_cols].apply(lambda x: x.str.split(',', expand=True) 
    ....:            .stack() 
    ....:            .astype(float) 
    ....:            .unstack() 
    ....:            .values.tolist()) 
    ....:    ) 

In [70]: df 
Out[70]: 
     vin vorgangid eventkm D_8_lamsoni_w_time  D_8_lamsoni_w_value 
0 V345578 295234545  13 [-1000.0, -980.0] [7.9921875, 11.984375] 
1 V346670 329781064  13 [-960.0, -940.0] [7.9921875, 11.984375] 

In [71]: type(df.loc[0, 'D_8_lamsoni_w_value'][0]) 
Out[71]: float 

ALTE Antwort:

Jetzt können wir Zahlen aufgeteilt in Liste Einrichtungen in der "Nummer" Spalten:

In [20]: df[['D_8_lamsoni_w_time', 'D_8_lamsoni_w_value']] = \ 
    df[['D_8_lamsoni_w_time', 'D_8_lamsoni_w_value']].apply(lambda x: x.str.split(',')) 
In [21]: df 
Out[21]: 
     vin vorgangid eventkm D_8_lamsoni_w_time  D_8_lamsoni_w_value 
0 V345578 295234545  13 [-1000.0, -980.0] [7.9921875, 11.984375] 
1 V346670 329781064  13 [-960.0, -940.0] [7.9921875, 11.984375] 
+0

Ihnen für den Vorschlag danken. Ich habe 2 Kommentare: 1) Ich denke, Zeile [20] kann in eine for-Schleife gepackt werden, wenn Sie viel mehr als 2 Spalten haben, aber dann wird es im Grunde das gleiche wie mein Ansatz, nein? 2) Ich denke, am Ende haben Sie immer noch eine Liste mit Strings, z. Geben Sie (df.ix [0,4] [0]) == 'str' – valenzio

+0

@valenzio, überprüfen Sie bitte den UPDATE-Abschnitt - ich habe den Code komplett neu geschrieben und beide Fragen beantwortet – MaxU

+0

Danke Kumpel, das sieht viel besser aus, aber Sie würden immer noch Ich brauche zwei for-Schleifen, wenn Sie wie 100 Einträge für Zeile 67 und 68 haben, suchte ich nach einer Lösung ähnlich wie Ami Tavory vorgeschlagen. Im Grunde ein Importbefehl mit den richtigen Parametern – valenzio

2

Sie können Parameter verwenden converters in read_csv und benutzerdefinierte Funktion für spliting definieren:

def f(x): 
    return [float(i) for i in x.split(',')] 

#after testing replace io.StringIO(temp) to filename 
df = pd.read_csv(io.StringIO(temp), 
       sep=";", 
       converters={'D_8_lamsoni_w_time':f, 'D_8_lamsoni_w_value':f}) 
print (df) 
     vin vorgangid eventkm D_8_lamsoni_w_time  D_8_lamsoni_w_value 
0 V345578 295234545  13 [-1000.0, -980.0] [7.9921875, 11.984375] 
1 V346670 329781064  13 [-960.0, -940.0] [7.9921875, 11.984375] 

Eine andere Lösung mit NaN in 4. und 5. Spalten arbeiten:

Sie können read_csv mit Separatoren ; verwenden und dann str.split auf 4. undanwendenSpalte von iloc ausgewählt und jeder Wert in list konvertieren float:

import pandas as pd 
import numpy as np 
import io 

temp=u"""vin;vorgangid;eventkm;D_8_lamsoni_w_time;D_8_lamsoni_w_value 
V345578;295234545;13;-1000.0,-980.0;7.9921875,11.984375 
V346670;329781064;13;-960.0,-940.0;7.9921875,11.984375""" 
#after testing replace io.StringIO(temp) to filename 
df = pd.read_csv(io.StringIO(temp), sep=";") 

print (df) 
     vin vorgangid eventkm D_8_lamsoni_w_time D_8_lamsoni_w_value 
0 V345578 295234545  13  -1000.0,-980.0 7.9921875,11.984375 
1 V346670 329781064  13  -960.0,-940.0 7.9921875,11.984375 

#split 4.th and 5th column and convert to numpy array 
df.iloc[:,3] = df.iloc[:,3].str.split(',').apply(lambda x: [float(i) for i in x]) 
df.iloc[:,4] = df.iloc[:,4].str.split(',').apply(lambda x: [float(i) for i in x]) 
print (df) 
     vin vorgangid eventkm D_8_lamsoni_w_time  D_8_lamsoni_w_value 
0 V345578 295234545  13 [-1000.0, -980.0] [7.9921875, 11.984375] 
1 V346670 329781064  13 [-960.0, -940.0] [7.9921875, 11.984375] 

Wenn Bedarf numpy arrays statt lists:

#split 4.th and 5th column and convert to numpy array 
df.iloc[:,3] = df.iloc[:,3].str.split(',').apply(lambda x: np.array([float(i) for i in x])) 
df.iloc[:,4] = df.iloc[:,4].str.split(',').apply(lambda x: np.array([float(i) for i in x])) 
print (df) 
     vin vorgangid eventkm D_8_lamsoni_w_time  D_8_lamsoni_w_value 
0 V345578 295234545  13 [-1000.0, -980.0] [7.9921875, 11.984375] 
1 V346670 329781064  13 [-960.0, -940.0] [7.9921875, 11.984375] 

print (type(df.iloc[0,3])) 
<class 'numpy.ndarray'> 

Ich versuche Ihre solutiuon zu verbessern:

a=0; 
csv_import=pd.read_csv(folder+FileName, ';') 
for col in csv_import.columns: 
    a += 1 
    if type(csv_import.ix[0, col])== str and a>3: 
     # string to list of strings 
     csv_import[col]=csv_import[col].apply(lambda x: [float(y) for y in x.split(',')]) 
+0

Vielen Dank für Ihre Eingabe, aber korrigieren Sie mich, wenn ich falsch liege, sieht das mühsamer aus als meine apply. – valenzio

+0

Ok, ich versuche, Ihre Lösung zu verbessern, überprüfen Sie bitte letzten Absatz in meiner Antwort. – jezrael

+0

sieht gut aus, aber ich denke, es gibt keine Möglichkeit, die for-Schleife zu vermeiden, ich dachte nur, es gibt eine Möglichkeit, den Import in einigen zu initialisieren So, dass es automatisch weiß, dass (',') getrennte Werte ein Array sind – valenzio

Verwandte Themen