我有一个代码,我正在修改这样的单元格:IBM["PNL"][2]=3
。它有效,但它出现了警告:
A value is trying to be set on a copy of a slice from a DataFrame
See the caveats in the documentation: http://pandas.pydata.org/pandas-docs/stable/indexing.html#indexing-view-versus-copy
从我在文章中可以阅读的内容来看,修改价值的正确方法是IBM.loc[2,"PNL"]=3
。但是,这对我不起作用,并且失败并出现以下错误:
Traceback (most recent call last):
File "<ipython-input-25-10debbad977d>", line 1, in <module>
IBM_dataframe.loc[0,"PNL"]
File "C:\Users\menkaur\Anaconda2\lib\site-packages\pandas\core\indexing.py", line 1310, in __getitem__
return self._getitem_tuple(key)
File "C:\Users\menkaur\Anaconda2\lib\site-packages\pandas\core\indexing.py", line 796, in _getitem_tuple
return self._getitem_lowerdim(tup)
File "C:\Users\menkaur\Anaconda2\lib\site-packages\pandas\core\indexing.py", line 922, in _getitem_lowerdim
section = self._getitem_axis(key, axis=i)
File "C:\Users\menkaur\Anaconda2\lib\site-packages\pandas\core\indexing.py", line 1482, in _getitem_axis
self._has_valid_type(key, axis)
File "C:\Users\menkaur\Anaconda2\lib\site-packages\pandas\core\indexing.py", line 1409, in _has_valid_type
key = self._convert_scalar_indexer(key, axis)
File "C:\Users\menkaur\Anaconda2\lib\site-packages\pandas\core\indexing.py", line 196, in _convert_scalar_indexer
return ax._convert_scalar_indexer(key, kind=self.name)
File "C:\Users\menkaur\Anaconda2\lib\site-packages\pandas\tseries\base.py", line 591, in _convert_scalar_indexer
self._invalid_indexer('index', key)
File "C:\Users\menkaur\Anaconda2\lib\site-packages\pandas\indexes\base.py", line 1284, in _invalid_indexer
kind=type(key)))
TypeError: cannot do index indexing on <class 'pandas.tseries.index.DatetimeIndex'> with these indexers [2] of <type 'int'>
现在,我很困惑
我做错了什么?
答案 0 :(得分:4)
现在不推荐使用.ix
,您有两种选择:
IBM.loc[IBM.index[2], "PNL"] = 3
这是基于标签的索引。由于您需要标签但是您有位置,因此使用IBM.index[2]
返回标签。或者,
IBM.iloc[2, IBM.columns.get_loc('PNL')] = 3
这是基于位置的索引。要获取列PNL
的位置,请使用get_loc
。
错误是因为您尝试对行使用基于位置的索引,但对列使用基于标签的索引。 .ix
旨在处理此类案例,但已弃用。 Here是@jezrael所指出的详细信息。
答案 1 :(得分:3)
假设IBM
是pd.DataFrame
,IBM["PNL"]
是pd.Series
。 []
(方括号)调用__getitem__
方法并返回一个系列对象。然后,您使用__getitem__
返回的系列调用IBM["PNL"][2]
方法,即[2]
部分。现在这很好,即使有点令人困惑。您尝试分配时出现问题。 IBM["PNL"][2] = 3
告诉pandas
分配给pd.Series
IBM["PNL"]
的第2个元素,该元素是"PNL"
数据框内IBM
列的视图......头晕了吗?
因此,答案是使用IBM
,loc
,iloc
,at
或iat
直接分配到set_value
数据框适当的指数。
loc
允许您将1-D数组作为索引器传递。数组可以是索引或列的切片(子集),也可以是布尔数组,其长度与索引或列相等。
特别注意:当传递标量索引器时,loc
可以分配之前不存在的新索引或列值。
# described by @ayhan
IBM.loc[IBM.index[2], 'PNL'] = 3
iloc
与loc
类似,除了位置而不是索引值。但是,您无法分配新列或索引。
# described by @ayhan
IBM.iloc[2, IBM.columns.get_loc('PNL')] = 3
at
与标量索引器的loc
非常相似。 无法对阵列索引器进行操作。 可以!分配新的索引和列
IBM.at[IBM.index[2], 'PNL'] = 3
iat
与iloc
类似。 无法在数组索引器中工作。 不能!分配新的索引和列。
IBM.iat[2, IBM.columns.get_loc('PNL')] = 3
set_value
与标量索引器的loc
非常相似。 无法对阵列索引器进行操作。 可以!分配新的索引和列
IBM.set_value(IBM.index[2], 'PNL', 3)
set_value
with takable=True
与iloc
类似。 无法在数组索引器中工作。 不能!分配新的索引和列。
IBM.set_value(2, IBM.columns.get_loc('PNL'), 3, takable=True)