您不需要改变values
属性。
尝试使用df.columns.values = ['a', 'b', 'c']
,您将得到:
AttributeError Traceback (most recent call last)
<ipython-input-61-e7e440adc404> in <module>()
AttributeError: can't set attribute
那是因为
pandas
检测到您正在尝试设置属性并停止了您。然而,它不能阻止您改变底层的
values
对象本身。当您使用
rename
时,
pandas
会跟进一堆清理工作。我已经粘贴了源代码。最终,您所做的是在不启动清理的情况下改变了值。您可以通过后续调用
_data.rename_axis
(示例可以在下面的源代码中看到)来启动它自己。这将强制运行清理,然后您就可以访问
['f']
。
df._data = df._data.rename_axis(lambda x: x, 0, True)
df['f']
0 7
1 8
2 9
Name: f, dtype: int64
故事寓意:以这种方式重命名列可能不是个好主意。
但这个故事变得更奇怪了。
没问题
df = pd.DataFrame({'a':[7,8,9],
'b':[1,3,5],
'c':[5,3,6]})
df.columns.values[0] = 'f'
df['f']
0 7
1 8
2 9
Name: f, dtype: int64
这不好
df = pd.DataFrame({'a':[7,8,9],
'b':[1,3,5],
'c':[5,3,6]})
print(df)
df.columns.values[0] = 'f'
df['f']
KeyError:
原来,我们可以在显示 df
之前修改 values
属性,这样它将会在第一次 display
时运行所有初始化操作。如果在修改 values
属性之前显示它,它将出现错误。
更奇怪的是
df = pd.DataFrame({'a':[7,8,9],
'b':[1,3,5],
'c':[5,3,6]})
print(df)
df.columns.values[0] = 'f'
df['f'] = 1
df['f']
f f
0 7 1
1 8 1
2 9 1
仿佛我们之前并不知道这是个坏主意...
rename
的来源
def rename(self, *args, **kwargs):
axes, kwargs = self._construct_axes_from_arguments(args, kwargs)
copy = kwargs.pop('copy', True)
inplace = kwargs.pop('inplace', False)
if kwargs:
raise TypeError('rename() got an unexpected keyword '
'argument "{0}"'.format(list(kwargs.keys())[0]))
if com._count_not_none(*axes.values()) == 0:
raise TypeError('must pass an index to rename')
def _get_rename_function(mapper):
if isinstance(mapper, (dict, ABCSeries)):
def f(x):
if x in mapper:
return mapper[x]
else:
return x
else:
f = mapper
return f
self._consolidate_inplace()
result = self if inplace else self.copy(deep=copy)
for axis in lrange(self._AXIS_LEN):
v = axes.get(self._AXIS_NAMES[axis])
if v is None:
continue
f = _get_rename_function(v)
baxis = self._get_block_manager_axis(axis)
result._data = result._data.rename_axis(f, axis=baxis, copy=copy)
result._clear_item_cache()
if inplace:
self._update_inplace(result._data)
else:
return result.__finalize__(self)
df.rename(columns={'a': 'f'})
是预期的方法。 - Jan Trienes