Repository: pandas-dev/pandas

Issue:
ERR/BUG: df2.fillna(df1) should raise NotImplementedError
from [SO](http://stackoverflow.com/questions/26002564/pandas-fillna-method-with-multiindex-nans-are-filled-with-wrong-columns)

`df2.fillna(df1)` should be implemented by:

`df2.where(df2.notnull(),df2,df1)`



Discussion:

Resolving patch:
diff --git a/pandas/core/generic.py b/pandas/core/generic.py
--- a/pandas/core/generic.py
+++ b/pandas/core/generic.py
@@ -2231,10 +2231,10 @@ def fillna(self, value=None, method=None, axis=0, inplace=False,
             Method to use for filling holes in reindexed Series
             pad / ffill: propagate last valid observation forward to next valid
             backfill / bfill: use NEXT valid observation to fill gap
-        value : scalar, dict, or Series
-            Value to use to fill holes (e.g. 0), alternately a dict/Series of
+        value : scalar, dict, Series, or DataFrame
+            Value to use to fill holes (e.g. 0), alternately a dict/Series/DataFrame of
             values specifying which value to use for each index (for a Series) or
-            column (for a DataFrame). (values not in the dict/Series will not be
+            column (for a DataFrame). (values not in the dict/Series/DataFrame will not be
             filled). This value cannot be a list.
         axis : {0, 1}, default 0
             * 0: fill column-by-column
@@ -2342,7 +2342,7 @@ def fillna(self, value=None, method=None, axis=0, inplace=False,
                                              inplace=inplace,
                                              downcast=downcast)
             elif isinstance(value, DataFrame) and self.ndim == 2:
-                raise NotImplementedError("can't use fillna with a DataFrame, use .where instead")
+                new_data = self.where(self.notnull(), value)
             else:
                 raise ValueError("invalid fill value with a %s" % type(value))
 


Test patch:
diff --git a/pandas/tests/test_frame.py b/pandas/tests/test_frame.py
--- a/pandas/tests/test_frame.py
+++ b/pandas/tests/test_frame.py
@@ -7630,6 +7630,29 @@ def test_fillna_dict_series(self):
         with assertRaisesRegexp(NotImplementedError, 'column by column'):
             df.fillna(df.max(1), axis=1)
 
+    def test_fillna_dataframe(self):
+        # GH 8377
+        df = DataFrame({'a': [nan, 1, 2, nan, nan],
+                        'b': [1, 2, 3, nan, nan],
+                        'c': [nan, 1, 2, 3, 4]},
+                       index = list('VWXYZ'))
+
+        # df2 may have different index and columns
+        df2 = DataFrame({'a': [nan, 10, 20, 30, 40],
+                         'b': [50, 60, 70, 80, 90],
+                         'foo': ['bar']*5},
+                        index = list('VWXuZ'))
+
+        result = df.fillna(df2)
+
+        # only those columns and indices which are shared get filled
+        expected = DataFrame({'a': [nan, 1, 2, nan, 40],
+                              'b': [1, 2, 3, nan, 90],
+                              'c': [nan, 1, 2, 3, 4]},
+                             index = list('VWXYZ'))
+
+        assert_frame_equal(result, expected)
+        
     def test_fillna_columns(self):
         df = DataFrame(np.random.randn(10, 10))
         df.values[:, ::2] = np.nan
@@ -7643,6 +7666,7 @@ def test_fillna_columns(self):
         expected = df.astype(float).fillna(method='ffill', axis=1)
         assert_frame_equal(result, expected)
 
+
     def test_fillna_invalid_method(self):
         with assertRaisesRegexp(ValueError, 'ffil'):
             self.frame.fillna(method='ffil')
@@ -7652,8 +7676,6 @@ def test_fillna_invalid_value(self):
         self.assertRaises(TypeError, self.frame.fillna, [1, 2])
         # tuple
         self.assertRaises(TypeError, self.frame.fillna, (1, 2))
-        # frame
-        self.assertRaises(NotImplementedError, self.frame.fillna, self.frame)
         # frame with series
         self.assertRaises(ValueError, self.frame.iloc[:,0].fillna, self.frame)