Skip to content

Commit b8d3c48

Browse files
committed
Fix assignment to missing columns
1 parent 25ad422 commit b8d3c48

File tree

2 files changed

+38
-0
lines changed

2 files changed

+38
-0
lines changed

pandas/core/frame.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2685,6 +2685,7 @@ def _setitem_array(self, key, value):
26852685
for k1, k2 in zip(key, value.columns):
26862686
self[k1] = value[k2]
26872687
else:
2688+
self.loc._ensure_listlike_indexer(key)
26882689
indexer = self.loc._get_listlike_indexer(
26892690
key, axis=1, raise_missing=False
26902691
)[1]

pandas/core/indexing.py

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
from pandas.util._decorators import Appender
99

1010
from pandas.core.dtypes.common import (
11+
is_hashable,
1112
is_integer,
1213
is_iterator,
1314
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) from e
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)