Skip to content

Commit 8818a2c

Browse files
committed
EHN: Allow DataFrame.fillna to accept a DataFrame as its fill value.
1 parent d1faa4a commit 8818a2c

File tree

3 files changed

+30
-8
lines changed

3 files changed

+30
-8
lines changed

doc/source/v0.15.0.txt

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -278,7 +278,7 @@ API changes
278278
- ``DataFrame.info()`` now ends its output with a newline character (:issue:`8114`)
279279
- add ``copy=True`` argument to ``pd.concat`` to enable pass thrue of complete blocks (:issue:`8252`)
280280

281-
- ``.fillna`` will now raise a ``NotImplementedError`` when passed a ``DataFrame`` (:issue:`8377`)
281+
282282

283283
.. _whatsnew_0150.dt:
284284

@@ -785,7 +785,7 @@ Enhancements
785785
meta-engine that automatically uses whichever version of openpyxl is
786786
installed. (:issue:`7177`)
787787

788-
788+
- ``DataFrame.fillna`` can now accept a ``DataFrame`` as a fill value (:issue:`8377`)
789789

790790
.. _whatsnew_0150.performance:
791791

pandas/core/generic.py

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2231,10 +2231,10 @@ def fillna(self, value=None, method=None, axis=0, inplace=False,
22312231
Method to use for filling holes in reindexed Series
22322232
pad / ffill: propagate last valid observation forward to next valid
22332233
backfill / bfill: use NEXT valid observation to fill gap
2234-
value : scalar, dict, or Series
2235-
Value to use to fill holes (e.g. 0), alternately a dict/Series of
2234+
value : scalar, dict, Series, or DataFrame
2235+
Value to use to fill holes (e.g. 0), alternately a dict/Series/DataFrame of
22362236
values specifying which value to use for each index (for a Series) or
2237-
column (for a DataFrame). (values not in the dict/Series will not be
2237+
column (for a DataFrame). (values not in the dict/Series/DataFrame will not be
22382238
filled). This value cannot be a list.
22392239
axis : {0, 1}, default 0
22402240
* 0: fill column-by-column
@@ -2342,7 +2342,7 @@ def fillna(self, value=None, method=None, axis=0, inplace=False,
23422342
inplace=inplace,
23432343
downcast=downcast)
23442344
elif isinstance(value, DataFrame) and self.ndim == 2:
2345-
raise NotImplementedError("can't use fillna with a DataFrame, use .where instead")
2345+
new_data = self.where(self.notnull(), value)
23462346
else:
23472347
raise ValueError("invalid fill value with a %s" % type(value))
23482348

pandas/tests/test_frame.py

Lines changed: 24 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7630,6 +7630,29 @@ def test_fillna_dict_series(self):
76307630
with assertRaisesRegexp(NotImplementedError, 'column by column'):
76317631
df.fillna(df.max(1), axis=1)
76327632

7633+
def test_fillna_dataframe(self):
7634+
# GH 8377
7635+
df = DataFrame({'a': [nan, 1, 2, nan, nan],
7636+
'b': [1, 2, 3, nan, nan],
7637+
'c': [nan, 1, 2, 3, 4]},
7638+
index = list('VWXYZ'))
7639+
7640+
# df2 may have different index and columns
7641+
df2 = DataFrame({'a': [nan, 10, 20, 30, 40],
7642+
'b': [50, 60, 70, 80, 90],
7643+
'foo': ['bar']*5},
7644+
index = list('VWXuZ'))
7645+
7646+
result = df.fillna(df2)
7647+
7648+
# only those columns and indices which are shared get filled
7649+
expected = DataFrame({'a': [nan, 1, 2, nan, 40],
7650+
'b': [1, 2, 3, nan, 90],
7651+
'c': [nan, 1, 2, 3, 4]},
7652+
index = list('VWXYZ'))
7653+
7654+
assert_frame_equal(result, expected)
7655+
76337656
def test_fillna_columns(self):
76347657
df = DataFrame(np.random.randn(10, 10))
76357658
df.values[:, ::2] = np.nan
@@ -7643,6 +7666,7 @@ def test_fillna_columns(self):
76437666
expected = df.astype(float).fillna(method='ffill', axis=1)
76447667
assert_frame_equal(result, expected)
76457668

7669+
76467670
def test_fillna_invalid_method(self):
76477671
with assertRaisesRegexp(ValueError, 'ffil'):
76487672
self.frame.fillna(method='ffil')
@@ -7652,8 +7676,6 @@ def test_fillna_invalid_value(self):
76527676
self.assertRaises(TypeError, self.frame.fillna, [1, 2])
76537677
# tuple
76547678
self.assertRaises(TypeError, self.frame.fillna, (1, 2))
7655-
# frame
7656-
self.assertRaises(NotImplementedError, self.frame.fillna, self.frame)
76577679
# frame with series
76587680
self.assertRaises(ValueError, self.frame.iloc[:,0].fillna, self.frame)
76597681

0 commit comments

Comments
 (0)