超级简单的列分配
pandas 数据框被实现为列的有序字典。
这意味着__getitem__
[]
不仅可以用于获取某个列,__setitem__
[] =
还可以用于分配新列。
例如,这个数据框可以通过简单地使用[]
访问器来添加一个列
size name color
0 big rose red
1 small violet blue
2 small tulip red
3 small harebell blue
df['protected'] = ['no', 'no', 'no', 'yes']
size name color protected
0 big rose red no
1 small violet blue no
2 small tulip red no
3 small harebell blue yes
请注意,即使数据帧的索引关闭,这也有效。
df.index = [3,2,1,0]
df['protected'] = ['no', 'no', 'no', 'yes']
size name color protected
3 big rose red no
2 small violet blue no
1 small tulip red no
0 small harebell blue yes
[]= 是要走的路,但要小心!
但是,如果您有 apd.Series
并尝试将其分配给索引关闭的数据框,您将遇到麻烦。参见示例:
df['protected'] = pd.Series(['no', 'no', 'no', 'yes'])
size name color protected
3 big rose red yes
2 small violet blue no
1 small tulip red no
0 small harebell blue no
这是因为pd.Series
默认情况下 a 具有从 0 到 n 枚举的索引。熊猫[] =
方法试图 变得“聪明”
究竟发生了什么。
当您使用该[] =
方法时,pandas 会使用左侧数据帧的索引和右侧系列的索引悄悄地执行外部连接或外部合并。df['column'] = series
边注
这很快就会导致认知失调,因为该方法试图根据输入做很多不同的事情,除非你只知道pandas 是如何工作[]=
的,否则无法预测结果。因此,我建议不要使用in 代码库,但在笔记本中探索数据时,这很好。[]=
绕过问题
如果您有一个pd.Series
并且希望它从上到下分配,或者如果您正在编写生产代码并且您不确定索引顺序,那么为此类问题进行保护是值得的。
您可以将 a 向下转换pd.Series
为 anp.ndarray
或 a list
,这样就可以了。
df['protected'] = pd.Series(['no', 'no', 'no', 'yes']).values
或者
df['protected'] = list(pd.Series(['no', 'no', 'no', 'yes']))
但这不是很明确。
一些编码员可能会说“嘿,这看起来多余,我会优化它”。
显式方式
将 的索引设置为pd.Series
的索引df
是显式的。
df['protected'] = pd.Series(['no', 'no', 'no', 'yes'], index=df.index)
或者更现实地说,您可能已经有一个pd.Series
可用的。
protected_series = pd.Series(['no', 'no', 'no', 'yes'])
protected_series.index = df.index
3 no
2 no
1 no
0 yes
现在可以分配
df['protected'] = protected_series
size name color protected
3 big rose red no
2 small violet blue no
1 small tulip red no
0 small harebell blue yes
替代方式df.reset_index()
由于索引不协调是问题所在,如果您觉得数据帧的索引不应该决定事情,您可以简单地删除索引,这应该更快,但它不是很干净,因为您的函数现在可能做两件事。
df.reset_index(drop=True)
protected_series.reset_index(drop=True)
df['protected'] = protected_series
size name color protected
0 big rose red no
1 small violet blue no
2 small tulip red no
3 small harebell blue yes
注意事项df.assign
虽然df.assign
更明确地说明您在做什么,但它实际上具有与上述所有相同的问题[]=
df.assign(protected=pd.Series(['no', 'no', 'no', 'yes']))
size name color protected
3 big rose red yes
2 small violet blue no
1 small tulip red no
0 small harebell blue no
请注意df.assign
,您的列没有被调用self
。它会导致错误。这很df.assign
臭,因为函数中有这类伪影。
df.assign(self=pd.Series(['no', 'no', 'no', 'yes'])
TypeError: assign() got multiple values for keyword argument 'self'
你可能会说,“好吧,那我就不用了self
”。但是谁知道这个函数将来会如何改变以支持新的论点。也许您的列名将成为熊猫新更新中的参数,从而导致升级问题。