Description
Pandas version checks
-
I have checked that this issue has not already been reported.
-
I have confirmed this bug exists on the latest version of pandas.
-
I have confirmed this bug exists on the main branch of pandas.
Reproducible Example
import pandas as pd
import numpy as np
df = pd.DataFrame.from_dict({'a': np.array([10], dtype='i8')})
# This doesn't work (raises AttributeError):
df.iloc[:, 0] = df['a'].astype('Int64')
# Neither does this:
df.loc[:, 'a'] = df['a'].astype('Int64')
# If you instead do this, it's fine:
#df['a'] = df['a'].astype('Int64')
assert df['a'].dtype == 'Int64'
Issue Description
The .iloc
line raises an AttributeError ('Series' object has no attribute '_hasna'). This is a regression because the same code works in e.g. 1.3.5 (and probably more recent versions too - this is just a particular one that I have access to).
~/opt/conda/envs/mamba/envs/py3_1/lib/python3.10/site-packages/pandas/core/indexing.py in ?(self, key, value)
881 indexer = self._get_setitem_indexer(key)
882 self._has_valid_setitem_indexer(key)
883
884 iloc = self if self.name == "iloc" else self.obj.iloc
--> 885 iloc._setitem_with_indexer(indexer, value, self.name)
~/opt/conda/envs/mamba/envs/py3_1/lib/python3.10/site-packages/pandas/core/indexing.py in ?(self, indexer, value, name)
1891 if take_split_path:
1892 # We have to operate column-wise
1893 self._setitem_with_indexer_split_path(indexer, value, name)
1894 else:
-> 1895 self._setitem_single_block(indexer, value, name)
~/opt/conda/envs/mamba/envs/py3_1/lib/python3.10/site-packages/pandas/core/indexing.py in ?(self, indexer, value, name)
2116 col = item_labels[indexer[info_axis]]
2117 if len(item_labels.get_indexer_for([col])) == 1:
2118 # e.g. test_loc_setitem_empty_append_expands_rows
2119 loc = item_labels.get_loc(col)
-> 2120 self._setitem_single_column(loc, value, indexer[0])
2121 return
2122
2123 indexer = maybe_convert_ix(*indexer) # e.g. test_setitem_frame_align
~/opt/conda/envs/mamba/envs/py3_1/lib/python3.10/site-packages/pandas/core/indexing.py in ?(self, loc, value, plane_indexer)
2083 try:
2084 self.obj._mgr.column_setitem(
2085 loc, plane_indexer, value, inplace_only=True
2086 )
-> 2087 except (ValueError, TypeError, LossySetitemError):
2088 # If we're setting an entire column and we can't do it inplace,
2089 # then we can use value's dtype (or inferred dtype)
2090 # instead of object
~/opt/conda/envs/mamba/envs/py3_1/lib/python3.10/site-packages/pandas/core/internals/managers.py in ?(self, loc, idx, value, inplace_only)
1302 # this manager is only created temporarily to mutate the values in place
1303 # so don't track references, otherwise the setitem
would perform CoW again
1304 col_mgr = self.iget(loc, track_ref=False)
1305 if inplace_only:
-> 1306 col_mgr.setitem_inplace(idx, value)
1307 else:
1308 new_mgr = col_mgr.setitem((idx,), value)
1309 self.iset(loc, new_mgr._block.values, inplace=True)
~/opt/conda/envs/mamba/envs/py3_1/lib/python3.10/site-packages/pandas/core/internals/managers.py in ?(self, indexer, value)
1987 if using_copy_on_write() and not self._has_no_reference(0):
1988 self.blocks = (self._block.copy(),)
1989 self._cache.clear()
1990
-> 1991 super().setitem_inplace(indexer, value)
~/opt/conda/envs/mamba/envs/py3_1/lib/python3.10/site-packages/pandas/core/internals/base.py in ?(self, indexer, value)
322 # EAs will do this validation in their own setitem methods.
323 if isinstance(arr, np.ndarray):
324 # Note: checking for ndarray instead of np.dtype means we exclude
325 # dt64/td64, which do their own validation.
--> 326 value = np_can_hold_element(arr.dtype, value)
327
328 if isinstance(value, np.ndarray) and value.ndim == 1 and len(value) == 1:
329 # NumPy 1.25 deprecation: numpy/numpy#10615
~/opt/conda/envs/mamba/envs/py3_1/lib/python3.10/site-packages/pandas/core/dtypes/cast.py in ?(dtype, element)
1792 raise LossySetitemError
1793 if not isinstance(tipo, np.dtype):
1794 # i.e. nullable IntegerDtype; we can put this into an ndarray
1795 # losslessly iff it has no NAs
-> 1796 if element._hasna:
1797 raise LossySetitemError
1798 return element
1799
~/opt/conda/envs/mamba/envs/py3_1/lib/python3.10/site-packages/pandas/core/generic.py in ?(self, name)
6200 and name not in self._accessors
6201 and self._info_axis._can_hold_identifiers_and_holds_name(name)
6202 ):
6203 return self[name]
-> 6204 return object.getattribute(self, name)
AttributeError: 'Series' object has no attribute '_hasna'
Expected Behavior
iloc
should not fail and the assert should pass.
Installed Versions
pandas : 2.1.1
numpy : 1.23.5
pytz : 2023.3
dateutil : 2.8.2
setuptools : 67.7.2
pip : 23.1.2
Cython : 3.0.0
pytest : 7.3.1
hypothesis : None
sphinx : None
blosc : None
feather : None
xlsxwriter : None
lxml.etree : 4.9.2
html5lib : 1.1
pymysql : None
psycopg2 : None
jinja2 : 3.1.2
IPython : 8.13.2
pandas_datareader : None
bs4 : 4.12.2
bottleneck : 1.3.7
dataframe-api-compat: None
fastparquet : None
fsspec : 2023.6.0
gcsfs : None
matplotlib : 3.7.1
numba : 0.56.4
numexpr : 2.8.7
odfpy : None
openpyxl : 3.1.2
pandas_gbq : None
pyarrow : 10.0.1
pyreadstat : None
pyxlsb : None
s3fs : 2023.6.0
scipy : 1.10.1
sqlalchemy : None
tables : None
tabulate : None
xarray : 2023.4.2
xlrd : 2.0.1
zstandard : None
tzdata : 2023.3
qtpy : 2.3.1
pyqt5 : None