2017-06-22 3 views
3

Wie kann ich eine komplexe Manipulation einer Panda-Spalte in eine neue Spalte machen? zum Beispiel:Panda Manipulation einer Spalte in eine neue Spalte

import pandas as pd 
import ast 

d = {'col1' : pd.Series([1, 2, 3, 4], index=['a', 'b', 'c', 'd']), 
    'col2' : pd.Series(['[9, 10]', '[10, 11]', '[11, 12]', '[12,13]'], 
       index=['a', 'b', 'c', 'd']) 
    } 
df = pd.DataFrame(d) 
print(df) 

So ist die letzte Spalte ist eigentlich eine Zeichenfolge, aber ich will es auf eine Liste konvertieren.

Ich habe versucht:

df['new'] = ast.literal_eval(df['col2') 

, die einen Fehler auslöst.

Ich habe viele andere Dinge ausprobiert und konnte nichts arbeiten.

Ich nehme an, es ist eine andere Möglichkeit, diese Frage zu beantworten:

In einer früheren Datei, habe ich meine df mit A sind die Elemente der Spalte zu sein und dann zu csv gespeichert. Beim Öffnen der CSV-Datei werden die Listen als Zeichenfolgen interpretiert. Eine andere Lösung wäre also, den ursprünglichen Panda so zu speichern, dass die Listen erhalten bleiben.

Antwort

3

json.loads funktioniert, weil Sie Ihre Listen gelten json. Sie json bereits importiert in pandas

df.assign(new=df.col2.apply(pd.io.json.loads)) 

    col1  col2  new 
a  1 [9, 10] [9, 10] 
b  2 [10, 11] [10, 11] 
c  3 [11, 12] [11, 12] 
d  4 [12,13] [12, 13] 

print(type(df.assign(new=df.col2.apply(pd.io.json.loads)).iloc[0, -1])) 

<class 'list'> 

Aus welchen Gründen auch immer verwenden, scheint json Parsen schneller als literal_eval

%timeit df.assign(new=df.col2.apply(pd.io.json.loads)) 
%timeit df.assign(new=df.col2.apply(literal_eval)) 
%timeit df.assign(new=[ast.literal_eval(x) for x in df['col2']]) 

kleine Daten

1000 loops, best of 3: 410 µs per loop 
1000 loops, best of 3: 468 µs per loop 
1000 loops, best of 3: 397 µs per loop 

große Daten

df = pd.concat([df] * 10000, ignore_index=True) 

100 loops, best of 3: 17.9 ms per loop 
1 loop, best of 3: 333 ms per loop 
1 loop, best of 3: 331 ms per loop 
2

Need apply oder list comprehension:

import ast 
df['new'] = df['col2'].apply(ast.literal_eval) 

df['new'] = [ast.literal_eval(x) for x in df['col2']] 

print(type(df.loc['a', 'new'])) 
<class 'list'> 
Verwandte Themen