2016-09-06 13 views
1

Ich bin neu in Pandas, ich verarbeite ein Dataset, wobei eine der Spalten Zeichenfolge mit Rohr (|) getrennte Werte ist. Jetzt habe ich eine Aufgabe, um irgendeinen Text in diesem | getrennten Feld zu entfernen, der bestimmte Kriterien nicht erfüllt.Kann Pandas Dataframe dtype der Liste haben?

Meine naive Vorgehensweise besteht darin, den Datenblock Zeile für Zeile zu wiederholen und das Feld in eine Liste zu zerlegen und auf diese Weise zu validieren. Schreiben Sie dann die geänderte Zeile zurück in den ursprünglichen Datenrahmen. Siehe dieses Metasample:

for index, row in dataframe.iterrows(): 
    fixed = [x[:29] for x in row['field'].split('|')] 
    dataframe.loc[index, 'field'] = "|".join(fixed) 

Gibt es eine bessere und vor allem schnellere Möglichkeit, dies zu tun?

+0

Auf den ersten Blick scheint dies wie ein Missbrauch der Datenstruktur mir einfach. Warum sollte eine Spalte eine Liste von Feldern sein, die durch ein Trennzeichen getrennt sind? Was sind die anderen Spalten? –

+0

Können Sie ein Beispiel für diese Spalte oder diesen Datenrahmen angeben? –

+0

@ juanpa.arrivillaga Nun, so kommen die Daten in der CSV zu mir. Es gibt auch andere Spalten, aber dies ist die einzige, die eine listenähnliche Struktur hat. Der Punkt ist, dass in den Originaldaten, die zu mir kommen, manchmal einer dieser Werte falsch ist ... und ich muss ihn abfiltern, bevor ich weiter mit dem Datensatz –

Antwort

2

IIUC können Sie:

dataframe = pd.DataFrame({'field':['aasd|bbuu|cccc|ddde|e','ffff|gggg|hhhh|i|j','cccc|u|k'], 
          'G':[4,5,6]}) 

print (dataframe) 
    G     field 
0 4 aasd|bbuu|cccc|ddde|e 
1 5  ffff|gggg|hhhh|i|j 
2 6    cccc|u|k 


print (dataframe.field.str.split('|', expand=True) 
          .stack() 
          .str[:2] #change to 29 
          .groupby(level=0) 
          .apply('|'.join)) 

0 aa|bb|cc|dd|e 
1  ff|gg|hh|i|j 
2   cc|u|k 
dtype: object 

Eine andere Lösung über Liste Verständnis:

dataframe['new'] = pd.Series([[x[:2] for x in y] for y in dataframe.field.str.split('|')], 
          index=dataframe.index) 
        .apply('|'.join) 
print (dataframe) 
    G     field   new 
0 4 aasd|bbuu|cccc|ddde|e aa|bb|cc|dd|e 
1 5  ffff|gggg|hhhh|i|j ff|gg|hh|i|j 
2 6    cccc|u|k   cc|u|k 

dataframe = pd.DataFrame({'field':['aasd|bbuu|cc|ddde|e','ffff|gggg|hhhh|i|j','cccc|u|k'], 
        'G':[4,5,6]}) 

print (dataframe) 
    G    field 
0 4 aasd|bbuu|cc|ddde|e 
1 5 ffff|gggg|hhhh|i|j 
2 6    cccc|u|k 

Wenn Bedarf Filter alle Werte mit Werten mehr als 2:

s = dataframe.field.str.split('|', expand=True).stack() 
print (s) 
0 0 aasd 
    1 bbuu 
    2  cc 
    3 ddde 
    4  e 
1 0 ffff 
    1 gggg 
    2 hhhh 
    3  i 
    4  j 
2 0 cccc 
    1  u 
    2  k 
dtype: object 

dataframe['new'] = s[s.str.len() < 3].groupby(level=0).apply('|'.join) 
print (dataframe) 

    G    field new 
0 4 aasd|bbuu|cc|ddde|e cc|e 
1 5 ffff|gggg|hhhh|i|j i|j 
2 6    cccc|u|k u|k 

Eine andere Lösung:

dataframe['new'] = pd.Series([[x for x in y if len(x) < 3] for y in dataframe.field.str.split('|')], 
           index=dataframe.index) 
        .apply('|'.join) 
print (dataframe) 
    G    field new 
0 4 aasd|bbuu|cc|ddde|e cc|e 
1 5 ffff|gggg|hhhh|i|j i|j 
2 6    cccc|u|k u|k 
+0

Danke, das ist sehr umfangreich, funktioniert –

Verwandte Themen