def combine(self, other, func, fill_value=None, overwrite=True):
other_idxlen = len(other.index)  <EOL>this, other = self.align(other, copy=False)<EOL>new_index = this.index<EOL>if other.empty and len(new_index) == len(self.index):<EOL><INDENT>return self.copy()<EOL><DEDENT>if self.empty and len(other) == other_idxlen:<EOL><INDENT>return other.copy()<EOL><DEDENT>new_columns = this.columns.union(other.columns)<EOL>do_fill = fill_value is not None<EOL>result = {}<EOL>for col in new_columns:<EOL><INDENT>series = this[col]<EOL>otherSeries = other[col]<EOL>this_dtype = series.dtype<EOL>other_dtype = otherSeries.dtype<EOL>this_mask = isna(series)<EOL>other_mask = isna(otherSeries)<EOL>if not overwrite and other_mask.all():<EOL><INDENT>result[col] = this[col].copy()<EOL>continue<EOL><DEDENT>if do_fill:<EOL><INDENT>series = series.copy()<EOL>otherSeries = otherSeries.copy()<EOL>series[this_mask] = fill_value<EOL>otherSeries[other_mask] = fill_value<EOL><DEDENT>if col not in self.columns:<EOL><INDENT>new_dtype = other_dtype<EOL>try:<EOL><INDENT>series = series.astype(new_dtype, copy=False)<EOL><DEDENT>except ValueError:<EOL><INDENT>pass<EOL><DEDENT><DEDENT>else:<EOL><INDENT>new_dtype = find_common_type([this_dtype, other_dtype])<EOL>if not is_dtype_equal(this_dtype, new_dtype):<EOL><INDENT>series = series.astype(new_dtype)<EOL><DEDENT>if not is_dtype_equal(other_dtype, new_dtype):<EOL><INDENT>otherSeries = otherSeries.astype(new_dtype)<EOL><DEDENT><DEDENT>arr = func(series, otherSeries)<EOL>arr = maybe_downcast_to_dtype(arr, this_dtype)<EOL>result[col] = arr<EOL><DEDENT>return self._constructor(result, index=new_index,<EOL>columns=new_columns)<EOL>
Perform column-wise combine with another DataFrame.

Combines a DataFrame with `other` DataFrame using `func`
to element-wise combine columns. The row and column indexes of the
resulting DataFrame will be the union of the two.

Parameters
----------
other : DataFrame
    The DataFrame to merge column-wise.
func : function
    Function that takes two series as inputs and return a Series or a
    scalar. Used to merge the two dataframes column by columns.
fill_value : scalar value, default None
    The value to fill NaNs with prior to passing any column to the
    merge func.
overwrite : bool, default True
    If True, columns in `self` that do not exist in `other` will be
    overwritten with NaNs.

Returns
-------
DataFrame
    Combination of the provided DataFrames.

See Also
--------
DataFrame.combine_first : Combine two DataFrame objects and default to
    non-null values in frame calling the method.

Examples
--------
Combine using a simple function that chooses the smaller column.

>>> df1 = pd.DataFrame({'A': [0, 0], 'B': [4, 4]})
>>> df2 = pd.DataFrame({'A': [1, 1], 'B': [3, 3]})
>>> take_smaller = lambda s1, s2: s1 if s1.sum() < s2.sum() else s2
>>> df1.combine(df2, take_smaller)
   A  B
0  0  3
1  0  3

Example using a true element-wise combine function.

>>> df1 = pd.DataFrame({'A': [5, 0], 'B': [2, 4]})
>>> df2 = pd.DataFrame({'A': [1, 1], 'B': [3, 3]})
>>> df1.combine(df2, np.minimum)
   A  B
0  1  2
1  0  3

Using `fill_value` fills Nones prior to passing the column to the
merge function.

>>> df1 = pd.DataFrame({'A': [0, 0], 'B': [None, 4]})
>>> df2 = pd.DataFrame({'A': [1, 1], 'B': [3, 3]})
>>> df1.combine(df2, take_smaller, fill_value=-5)
   A    B
0  0 -5.0
1  0  4.0

However, if the same element in both dataframes is None, that None
is preserved

>>> df1 = pd.DataFrame({'A': [0, 0], 'B': [None, 4]})
>>> df2 = pd.DataFrame({'A': [1, 1], 'B': [None, 3]})
>>> df1.combine(df2, take_smaller, fill_value=-5)
    A    B
0  0 -5.0
1  0  3.0

Example that demonstrates the use of `overwrite` and behavior when
the axis differ between the dataframes.

>>> df1 = pd.DataFrame({'A': [0, 0], 'B': [4, 4]})
>>> df2 = pd.DataFrame({'B': [3, 3], 'C': [-10, 1], }, index=[1, 2])
>>> df1.combine(df2, take_smaller)
     A    B     C
0  NaN  NaN   NaN
1  NaN  3.0 -10.0
2  NaN  3.0   1.0

>>> df1.combine(df2, take_smaller, overwrite=False)
     A    B     C
0  0.0  NaN   NaN
1  0.0  3.0 -10.0
2  NaN  3.0   1.0

Demonstrating the preference of the passed in dataframe.

>>> df2 = pd.DataFrame({'B': [3, 3], 'C': [1, 1], }, index=[1, 2])
>>> df2.combine(df1, take_smaller)
   A    B   C
0  0.0  NaN NaN
1  0.0  3.0 NaN
2  NaN  3.0 NaN

>>> df2.combine(df1, take_smaller, overwrite=False)
     A    B   C
0  0.0  NaN NaN
1  0.0  3.0 1.0
2  NaN  3.0 1.0