Skip to content

Commit 68e5c59

Browse files
committed
Merge pull request #8388 from unutbu/fillna-df
EHN: Allow DataFrame.fillna to accept a DataFrame as its fill value.
2 parents df3224f + 8818a2c commit 68e5c59

File tree

3 files changed

+30
-8
lines changed

3 files changed

+30
-8
lines changed

doc/source/v0.15.0.txt

+2-2
Original file line numberDiff line numberDiff line change
@@ -285,7 +285,7 @@ API changes
285285
- ``DataFrame.info()`` now ends its output with a newline character (:issue:`8114`)
286286
- add ``copy=True`` argument to ``pd.concat`` to enable pass thrue of complete blocks (:issue:`8252`)
287287

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

290290
.. _whatsnew_0150.dt:
291291

@@ -793,7 +793,7 @@ Enhancements
793793
meta-engine that automatically uses whichever version of openpyxl is
794794
installed. (:issue:`7177`)
795795

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

798798
.. _whatsnew_0150.performance:
799799

pandas/core/generic.py

+4-4
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

+24-2
Original file line numberDiff line numberDiff line change
@@ -7632,6 +7632,29 @@ def test_fillna_dict_series(self):
76327632
with assertRaisesRegexp(NotImplementedError, 'column by column'):
76337633
df.fillna(df.max(1), axis=1)
76347634

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

7671+
76487672
def test_fillna_invalid_method(self):
76497673
with assertRaisesRegexp(ValueError, 'ffil'):
76507674
self.frame.fillna(method='ffil')
@@ -7654,8 +7678,6 @@ def test_fillna_invalid_value(self):
76547678
self.assertRaises(TypeError, self.frame.fillna, [1, 2])
76557679
# tuple
76567680
self.assertRaises(TypeError, self.frame.fillna, (1, 2))
7657-
# frame
7658-
self.assertRaises(NotImplementedError, self.frame.fillna, self.frame)
76597681
# frame with series
76607682
self.assertRaises(ValueError, self.frame.iloc[:,0].fillna, self.frame)
76617683

0 commit comments

Comments
 (0)