2013-06-13 3 views
67

Die einfache Aufgabe, eine Zeile zu einem pandas.DataFrame Objekt hinzufügen, scheint schwer zu erreichen. Es gibt 3 Stackoverflow-Fragen in diesem Zusammenhang, von denen keine eine funktionierende Antwort gibt.Python pandas: füllen einen Datenblock Zeile für Zeile

Hier ist, was ich versuche zu tun. Ich habe einen DataFrame, von dem ich sowohl die Form als auch die Namen der Zeilen und Spalten kenne.

>>> df = pandas.DataFrame(columns=['a','b','c','d'], index=['x','y','z']) 
>>> df 
    a b c d 
x NaN NaN NaN NaN 
y NaN NaN NaN NaN 
z NaN NaN NaN NaN 

Jetzt habe ich eine Funktion, um die Werte der Zeilen iterativ zu berechnen. Wie kann ich eine der Zeilen mit einem Wörterbuch oder einem pandas.Series ausfüllen? Hier sind verschiedene Versuche, die fehlgeschlagen sind:

>>> y = {'a':1, 'b':5, 'c':2, 'd':3} 
>>> df['y'] = y 
AssertionError: Length of values does not match length of index 

Anscheinend versuchte es, eine Spalte anstelle einer Zeile hinzuzufügen.

>>> y = {'a':1, 'b':5, 'c':2, 'd':3} 
>>> df.join(y) 
AttributeError: 'builtin_function_or_method' object has no attribute 'is_unique' 

Sehr wenig informative Fehlermeldung.

>>> y = {'a':1, 'b':5, 'c':2, 'd':3} 
>>> df.set_value(index='y', value=y) 
TypeError: set_value() takes exactly 4 arguments (3 given) 

Scheinbar nur zum Setzen einzelner Werte im Datenrahmen.

>>> y = {'a':1, 'b':5, 'c':2, 'd':3} 
>>> df.append(y) 
Exception: Can only append a Series if ignore_index=True 

Nun, ich will nicht, um den Index zu ignorieren, sonst hier ist das Ergebnis:

>>> df.append(y, ignore_index=True) 
    a b c d 
0 NaN NaN NaN NaN 
1 NaN NaN NaN NaN 
2 NaN NaN NaN NaN 
3 1 5 2 3 

Es hat die Spaltennamen mit den Werten ausrichten, aber die Zeilenbeschriftungen verloren.

>>> y = {'a':1, 'b':5, 'c':2, 'd':3} 
>>> df.ix['y'] = y 
>>> df 
            a         b \ 
x        NaN        NaN 
y {'a': 1, 'c': 2, 'b': 5, 'd': 3} {'a': 1, 'c': 2, 'b': 5, 'd': 3} 
z        NaN        NaN 

            c         d 
x        NaN        NaN 
y {'a': 1, 'c': 2, 'b': 5, 'd': 3} {'a': 1, 'c': 2, 'b': 5, 'd': 3} 
z        NaN        NaN 

Das ist auch kläglich gescheitert.

Also, wie machst du es?

Antwort

53

df['y'] gesetzt eine Spalte

da Sie eine Zeile setzen möchten, verwenden Sie .loc

Beachten Sie, dass .ix Äquivalent hier ist, versagt bei Ihnen, weil Sie ein Wörterbuch zu jedem Element der Reihe zuzuordnen versucht y wahrscheinlich nicht das, was Sie wollen; Umwandlung in eine Serie Pandas sagt , dass Sie die Eingabe ausrichten möchten (zum Beispiel müssen Sie dann alle Elemente nicht angeben)

In [7]: df = pandas.DataFrame(columns=['a','b','c','d'], index=['x','y','z']) 

In [8]: df.loc['y'] = pandas.Series({'a':1, 'b':5, 'c':2, 'd':3}) 

In [9]: df 
Out[9]: 
    a b c d 
x NaN NaN NaN NaN 
y 1 5 2 3 
z NaN NaN NaN NaN 
+0

ich sehe. Also definiert das Attribut 'loc' des Datenrahmens ein spezielles' __setitem__', das die Magie ausführt, die ich vermute. – xApple

+0

Können Sie dies in einem Durchgang konstruieren (d. H. Mit Spalten, Index und y)? –

+3

Also, wenn ich eine Reihe auf einmal generieren kann, wie würde ich den Datenrahmen optimal aufbauen? – xApple

10

Diese eine einfachere Version

df = DataFrame(columns=('col1', 'col2', 'col3')) 
for i in range(5): 
    df.loc[i] = ['<some value for first>','<some value for second>','<some value for third>']` 
+2

möchte nur fragen, ist diese CPU und Speicher effizient? – czxttkl

+1

Wie kann ich die letzte Zeile von df wissen, also lege ich jedes Mal an die letzte Zeile an? – pashute

21

ist Mein Ansatz war, aber ich kann nicht garantieren, dass dies die schnellste Lösung ist.

df = pd.Dataframe(columns=["firstname", "lastname"]) 
df = df.append({ 
    "firstname": "John", 
    "lastname": "Johny" 
     }, ignore_index=True) 
+2

Das hat für mich super funktioniert und ich mag die Tatsache, dass Sie die Daten explizit an den Datenrahmen "anhängen". –

+0

Beachten Sie, dass bei dieser Antwort für jede Zeile der Spaltenname angehängt werden muss. Gleiches für die angenommene Antwort. – pashute

3

Wenn Ihre Eingabezeilen-Listen statt Wörterbücher sind, dann ist die folgende eine einfache Lösung:

import pandas as pd 
list_of_lists = [] 
list_of_lists.append([1,2,3]) 
list_of_lists.append([4,5,6]) 

pd.DataFrame(list_of_lists, columns=['A', 'B', 'C']) 
# A B C 
# 0 1 2 3 
# 1 4 5 6 
+0

aber was mache ich, wenn ich einen Multiindex habe? df1 = pd.DataFrame (Liste_der_Listen, Spalten ['A', 'B', 'C'], Index = ['A', 'B']) funktioniert nicht. Falsche Form. Also wie? – pashute