超简单的列分配
将熊猫数据框实现为列的有序字典。
这意味着__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
[] =是要走的路,但要当心!
但是,如果您有一个pd.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
边注
这很快就会引起认知失调,因为该[]=
方法试图根据输入来做很多不同的事情,除非您只知道熊猫是如何工作的,否则无法预测结果。因此,我建议不要使用[]=
in代码库,但是在笔记本中浏览数据时可以使用。
解决问题
如果您有一个pd.Series
并且希望从上到下分配它,或者您正在编码生产性代码并且不确定索引顺序,那么为此类问题提供保护是值得的。
您可以将转换pd.Series
为a np.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
”。但是谁知道这个函数将来会如何变化以支持新的论点。也许您的列名将成为熊猫新更新中的一个参数,从而导致升级问题。