我很难理解列命名约定背后的概念,因为以下尝试创建新列的尝试似乎失败:
(1, 2)
(2, 3)
(3, 1)
给出以下结果:
然而,如果我尝试通过替换以下行来创建列b,则没有错误消息,但数据帧df仅保留列a和c。
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
大熊猫做了什么,为什么我的命令不正确?
答案 0 :(得分:5)
您所做的是向您的df添加属性b
:
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
但我们发现没有添加新列:
In [73]:
df.columns
Out[73]:
Index(['a', 'c'], dtype='object')
这意味着如果我们尝试KeyError
,我们会得到df['b']
,为了避免这种歧义,您在分配时应始终使用方括号。
例如,如果您有一个名为index
或sum
或max
的列,那么执行df.index
将返回索引而不是索引列,同样{{1并且df.sum
会搞砸那些df方法。
我强烈建议总是使用方括号,避免任何歧义,最新的ipython能够使用方括号来解析列名。将数据帧视为系列的字典也很有用,其中使用方括号分配和返回列是有意义的
答案 1 :(得分:4)
始终使用方括号分配列
点符号方便访问数据框中的列。如果它们与现有属性冲突(例如,如果您有一个名为“max”的列),那么您需要使用方括号来访问该列,例如df['max']
。当列名称包含空格时,您还需要使用方括号,例如df['max value']
。
DataFrame只是一个具有常用属性和方法的对象。如果使用点表示法进行赋值,则表示正在为dataframe对象创建属性或方法。因此,df.val = 2
会为df
分配一个值为2的属性val
。这与df['val'] = 2
非常不同,columns=list('ac'))
在数据框中创建一个新列,并为该列中的每个元素指定值2。
为安全起见,使用方括号表示法将始终提供正确的结果。
顺便说一下,你的columns
没有做任何事情,因为你只是创建了一个从未使用过的名为df.columns = list('ac')
的变量。你可能意味着pd.DataFrame({'a': [...], 'b': [...]})
,但是你已经在创建数据框时分配了这些,所以我不确定这行代码的目的是什么。并且请记住,字典是无序的,因此images/pic1.png
可能会返回包含列['b','a']的数据框。如果是这种情况,那么分配列名可能会混淆列标题。
答案 2 :(得分:1)
问题与如何在python中处理属性有关。 python中没有为类设置新属性的限制,例如,您可以执行类似
的操作df.myspecialstuff = ["dog", "cat", 5]
所以当你做
这样的作业时df.b = 10*df.a
是否要添加属性或新列以及设置属性是不明确的。实际查看正在发生的事情的最简单方法是使用pdb并逐步执行代码
import pdb
x = df.a
pdb.run("df.a1 = x")
这将进入__setattr__()
,而pdb.run("df['a2'] = x")
将进入__setitem__()