2016-04-28 14 views
2

Ich kämpfe das Konzept hinter Spalte Namenskonventionen zu verstehen, da eine der folgenden Versuche, eine neue Spalte zu erstellen - erscheint fehlschlagen:Pandas Spalte Schaffung

from numpy.random import randn 
import pandas as pd 

df = pd.DataFrame({'a':range(0,10,2), 'c':range(0,1000,200)}, 
columns=list('ac')) 
df['b'] = 10*df.a 
df 

das folgende Ergebnis ergibt:

enter image description here

doch wenn ich mit der folgenden Zeile durch Substitution Spalte b zu erstellen, um zu versuchen war, gibt es keine Fehlermeldung, aber der Datenrahmen df bleibt nur die Spalten a und c.

df.b = 10*df.a ### rather than the previous df['b'] = 10*df.a ### 

Was hat Pandas getan und warum ist mein Befehl falsch?

+0

Schritt wird Wenn bereits Spalte b vorhanden ist, dann df.b = 10 * df.a funktioniert! – thescoop

Antwort

5

Was haben Sie war ein Attribut b zu Ihrem df hinzufügen:

In [70]: 
df.b = 10*df.a 
df.b 

Out[70]: 
0  0 
1 20 
2 40 
3 60 
4 80 
Name: a, dtype: int32 

aber wir sehen, dass keine neue Spalte hinzugefügt wurde:

In [73]:  
df.columns 

Out[73]: 
Index(['a', 'c'], dtype='object') 

was bedeutet, dass wir eine KeyError, wenn wir versuchten, df['b'], um diese Mehrdeutigkeit zu vermeiden, sollten Sie beim Zuweisen immer eckige Klammern verwenden.

zum Beispiel, wenn Sie hatte eine Spalte index oder sum oder max dann df.index zurückkehren würde Methoden, um den Index und der Index Spalte und in ähnlicher Weise df.sum und df.max würde vermasseln diese df tun benannt.

Ich rate dringend, immer eckige Klammern zu verwenden, es vermeidet jede Mehrdeutigkeit und das neueste ipython ist in der Lage, Spaltennamen in eckigen Klammern aufzulösen. Es ist auch nützlich ein Datenrahmens als dict von Serie zu denken, in denen es sinnvoll ist eckige Klammern zu verwenden für die Zuordnung und Rückgabe eine Spalte

+0

Punktnotation funktioniert auch nicht für ganzzahlige Indizes (dh 'df.1') – ayhan

+1

@ayhan Das liegt daran, dass es sich um einen ungültigen Namen für ein Attribut handelt. Das Gleiche würde passieren, wenn Sie ein Leerzeichen in einem Spaltennamen hätten und versuchen würden, darauf zuzugreifen Verwenden Sie die Punktnotation, siehe http://stackoverflow.com/questions/10120295/valid-characters-in-a-python-class-name – EdChum

4

immer eckige Klammern für die Zuordnung von Spalten

Dot-Notation ist eine Bequemlichkeit für Zugriff auf Spalten in einem Datenrahmen. Wenn sie mit vorhandenen Eigenschaften in Konflikt stehen (z. B. wenn Sie eine Spalte mit dem Namen "max" hatten), müssen Sie eckige Klammern verwenden, um auf diese Spalte zuzugreifen, z. df['max']. Sie müssen auch eckige Klammern verwenden, wenn der Spaltenname Leerzeichen enthält, z. df['max value'].

Ein DataFrame ist nur ein Objekt mit den üblichen Eigenschaften und Methoden. Wenn Sie die Punktnotation für die Zuweisung verwenden, erstellen Sie eine Eigenschaft oder Methode für das Datenrahmenobjekt. So wird df.val = 2df mit einer Eigenschaft val zuweisen, die einen Wert von zwei hat. Dies unterscheidet sich sehr von df['val'] = 2, die eine neue Spalte im Datenrahmen erstellt und jedem Element in dieser Spalte den Wert von zwei zuweist.

Um sicher zu sein, wird die Verwendung der eckigen Klammernotation immer das korrekte Ergebnis liefern.

Nebenbei, Ihre columns=list('ac')) tut nichts, da Sie nur eine Variable mit dem Namen columns erstellen, die nie verwendet wird.Sie haben vielleicht df.columns = list('ac') gemeint, aber Sie haben diese bereits bei der Erstellung des Datenrahmens zugewiesen, also bin ich mir nicht sicher, was die Absicht mit dieser Codezeile ist. Denken Sie daran, dass Wörterbücher ungeordnet sind, sodass pd.DataFrame({'a': [...], 'b': [...]}) möglicherweise einen Datenrahmen mit den Spalten ['b', 'a'] zurückgeben kann. Wenn dies der Fall wäre, könnte die Zuweisung von Spaltennamen möglicherweise die Spaltenüberschriften vertauschen.

1

Das Problem hat damit zu tun, wie Eigenschaften in Python behandelt werden. Es gibt keine Beschränkung in Python eine neue Eigenschaften für eine Klasse zu setzen, so zum Beispiel könnten Sie so etwas wie

df.myspecialstuff = ["dog", "cat", 5] 

So tun, wenn Sie tun Zuordnung wie

df.b = 10*df.a 

Es ist nicht eindeutig, ob Sie wollen Fügen Sie eine Eigenschaft oder eine neue Spalte hinzu, und eine Eigenschaft wird festgelegt. Der einfachste Weg, um tatsächlich zu sehen, was mit diesem los ist, ist PDB und Schritt durch den Code Dieser

import pdb 
x = df.a 
pdb.run("df.a1 = x") 

zu verwenden, wird in Schritt die __setattr__() während pdb.run("df['a2'] = x") in __setitem__()