Skip to content

Commit 8934195

Browse files
authored
REF: separate out setitem_with_indexer helpers (#37481)
1 parent 293f2fa commit 8934195

File tree

1 file changed

+63
-54
lines changed

1 file changed

+63
-54
lines changed

pandas/core/indexing.py

+63-54
Original file line numberDiff line numberDiff line change
@@ -1673,66 +1673,14 @@ def _setitem_with_indexer(self, indexer, value):
16731673

16741674
# we have an equal len Frame
16751675
if isinstance(value, ABCDataFrame):
1676-
sub_indexer = list(indexer)
1677-
multiindex_indexer = isinstance(labels, ABCMultiIndex)
1678-
# TODO: we are implicitly assuming value.columns is unique
1679-
unique_cols = value.columns.is_unique
1680-
1681-
if not unique_cols and value.columns.equals(self.obj.columns):
1682-
# We assume we are already aligned, see
1683-
# test_iloc_setitem_frame_duplicate_columns_multiple_blocks
1684-
for loc in ilocs:
1685-
item = item_labels[loc]
1686-
if item in value:
1687-
sub_indexer[info_axis] = item
1688-
v = self._align_series(
1689-
tuple(sub_indexer),
1690-
value.iloc[:, loc],
1691-
multiindex_indexer,
1692-
)
1693-
else:
1694-
v = np.nan
1695-
1696-
self._setitem_single_column(loc, v, plane_indexer)
1697-
1698-
elif not unique_cols:
1699-
raise ValueError(
1700-
"Setting with non-unique columns is not allowed."
1701-
)
1702-
1703-
else:
1704-
for loc in ilocs:
1705-
item = item_labels[loc]
1706-
if item in value:
1707-
sub_indexer[info_axis] = item
1708-
v = self._align_series(
1709-
tuple(sub_indexer), value[item], multiindex_indexer
1710-
)
1711-
else:
1712-
v = np.nan
1713-
1714-
self._setitem_single_column(loc, v, plane_indexer)
1676+
self._setitem_with_indexer_frame_value(indexer, value)
17151677

17161678
# we have an equal len ndarray/convertible to our labels
17171679
# hasattr first, to avoid coercing to ndarray without reason.
17181680
# But we may be relying on the ndarray coercion to check ndim.
17191681
# Why not just convert to an ndarray earlier on if needed?
17201682
elif np.ndim(value) == 2:
1721-
1722-
# note that this coerces the dtype if we are mixed
1723-
# GH 7551
1724-
value = np.array(value, dtype=object)
1725-
if len(ilocs) != value.shape[1]:
1726-
raise ValueError(
1727-
"Must have equal len keys and value "
1728-
"when setting with an ndarray"
1729-
)
1730-
1731-
for i, loc in enumerate(ilocs):
1732-
# setting with a list, re-coerces
1733-
self._setitem_single_column(
1734-
loc, value[:, i].tolist(), plane_indexer
1735-
)
1683+
self._setitem_with_indexer_2d_value(indexer, value)
17361684

17371685
elif (
17381686
len(labels) == 1
@@ -1766,6 +1714,67 @@ def _setitem_with_indexer(self, indexer, value):
17661714
else:
17671715
self._setitem_single_block(indexer, value)
17681716

1717+
def _setitem_with_indexer_2d_value(self, indexer, value):
1718+
# We get here with np.ndim(value) == 2, excluding DataFrame,
1719+
# which goes through _setitem_with_indexer_frame_value
1720+
plane_indexer = indexer[:1]
1721+
1722+
ilocs = self._ensure_iterable_column_indexer(indexer[1])
1723+
1724+
# GH#7551 Note that this coerces the dtype if we are mixed
1725+
value = np.array(value, dtype=object)
1726+
if len(ilocs) != value.shape[1]:
1727+
raise ValueError(
1728+
"Must have equal len keys and value when setting with an ndarray"
1729+
)
1730+
1731+
for i, loc in enumerate(ilocs):
1732+
# setting with a list, re-coerces
1733+
self._setitem_single_column(loc, value[:, i].tolist(), plane_indexer)
1734+
1735+
def _setitem_with_indexer_frame_value(self, indexer, value: "DataFrame"):
1736+
ilocs = self._ensure_iterable_column_indexer(indexer[1])
1737+
1738+
sub_indexer = list(indexer)
1739+
plane_indexer = indexer[:1]
1740+
1741+
multiindex_indexer = isinstance(self.obj.columns, ABCMultiIndex)
1742+
1743+
unique_cols = value.columns.is_unique
1744+
1745+
if not unique_cols and value.columns.equals(self.obj.columns):
1746+
# We assume we are already aligned, see
1747+
# test_iloc_setitem_frame_duplicate_columns_multiple_blocks
1748+
for loc in ilocs:
1749+
item = self.obj.columns[loc]
1750+
if item in value:
1751+
sub_indexer[1] = item
1752+
val = self._align_series(
1753+
tuple(sub_indexer),
1754+
value.iloc[:, loc],
1755+
multiindex_indexer,
1756+
)
1757+
else:
1758+
val = np.nan
1759+
1760+
self._setitem_single_column(loc, val, plane_indexer)
1761+
1762+
elif not unique_cols:
1763+
raise ValueError("Setting with non-unique columns is not allowed.")
1764+
1765+
else:
1766+
for loc in ilocs:
1767+
item = self.obj.columns[loc]
1768+
if item in value:
1769+
sub_indexer[1] = item
1770+
val = self._align_series(
1771+
tuple(sub_indexer), value[item], multiindex_indexer
1772+
)
1773+
else:
1774+
val = np.nan
1775+
1776+
self._setitem_single_column(loc, val, plane_indexer)
1777+
17691778
def _setitem_single_column(self, loc: int, value, plane_indexer):
17701779
# positional setting on column loc
17711780
pi = plane_indexer

0 commit comments

Comments
 (0)