Skip to content

Commit dd16c45

Browse files
committed
Fix assignment to missing columns
1 parent ded66b4 commit dd16c45

File tree

2 files changed

+38
-0
lines changed

2 files changed

+38
-0
lines changed

pandas/core/frame.py

+1
Original file line numberDiff line numberDiff line change
@@ -2686,6 +2686,7 @@ def _setitem_array(self, key, value):
26862686
for k1, k2 in zip(key, value.columns):
26872687
self[k1] = value[k2]
26882688
else:
2689+
self.loc._ensure_listlike_indexer(key)
26892690
indexer = self.loc._get_listlike_indexer(
26902691
key, axis=1, raise_missing=False
26912692
)[1]

pandas/core/indexing.py

+37
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99

1010
from pandas.core.dtypes.common import (
1111
is_float,
12+
is_hashable,
1213
is_integer,
1314
is_iterator,
1415
is_list_like,
@@ -581,6 +582,9 @@ def _get_setitem_indexer(self, key):
581582
"""
582583
Convert a potentially-label-based key into a positional indexer.
583584
"""
585+
if self.name == "loc":
586+
self._ensure_listlike_indexer(key)
587+
584588
if self.axis is not None:
585589
return self._convert_tuple(key, is_setter=True)
586590

@@ -611,6 +615,39 @@ def _get_setitem_indexer(self, key):
611615
raise
612616
raise IndexingError(key)
613617

618+
def _ensure_listlike_indexer(self, key):
619+
"""
620+
Ensure that a list-like of column labels are all present by adding them if
621+
they do not already exist.
622+
623+
Parameters
624+
----------
625+
key : _LocIndexer key or list-like of column labels
626+
Target labels.
627+
"""
628+
column_axis = 1
629+
630+
# column only exists in 2-dimensional DataFrame
631+
if self.ndim != 2:
632+
return
633+
634+
if isinstance(key, tuple):
635+
# key may be a tuple if key is a _LocIndexer key
636+
# in that case, set key to the column part of key
637+
key = key[column_axis]
638+
639+
if (
640+
not isinstance(self.obj._get_axis(column_axis), ABCMultiIndex)
641+
and is_list_like_indexer(key)
642+
and not com.is_bool_indexer(key)
643+
and all(is_hashable(k) for k in key)
644+
):
645+
for k in key:
646+
try:
647+
self.obj[k]
648+
except KeyError:
649+
self.obj[k] = np.nan
650+
614651
def __setitem__(self, key, value):
615652
if isinstance(key, tuple):
616653
key = tuple(com.apply_if_callable(x, self.obj) for x in key)

0 commit comments

Comments
 (0)