Repository: pandas-dev/pandas

Issue:
DOC: DataFrame.update() fails to change values in calling dataframe if new value is NaN
#### Code Sample, a copy-pastable example if possible

```python
# Define dataframe
tempDF1 = pd.DataFrame({'c1':[1,2,3,4,5],
                       'c2':[True,True,False,False,True]})

# Select part of original dataframe
tempDF2 = tempDF1.loc[tempDF1['c2']==True,:].copy()

print('Original dataframe')
print(tempDF1)
print('\nSelection of dataframe')
print(tempDF2)

# Make some changes to selection
tempDF2.loc[:,'c1'] = tempDF2.loc[:,'c1'] + 100
tempDF2.iloc[2,0] = np.nan

# Update original dataframe with new values
tempDF1.update(tempDF2,overwrite=True)

print('\nSelection of dataframe - with changes')
print(tempDF2)
print('\nUpdated original dataframe')
print(tempDF1)

```
#### Problem description

DataFrame.update() function fails to update a dataframe with new NaN values. However, non-NaN values are updated to original dataframe with no issues (except the dtype of the dataframe is altered in the update process, namely int64 changed to float64).

#### Expected Output

Expected output would be 

```
      c1     c2
0  101   True
1  102   True
2    3  False
3    4  False
4  NaN   True
```

However, actual output is:

```
      c1     c2
0  101.0   True
1  102.0   True
2    3.0  False
3    4.0  False
4    5.0   True
```
#### Output of ``pd.show_versions()``

INSTALLED VERSIONS
------------------
commit: None
python: 3.4.6.final.0
python-bits: 64
OS: Darwin
OS-release: 15.6.0
machine: x86_64
processor: i386
byteorder: little
LC_ALL: None
LANG: en_GB.UTF-8
LOCALE: en_GB.UTF-8

pandas: 0.20.2
pytest: None
pip: 9.0.1
setuptools: 34.3.3
Cython: None
numpy: 1.13.0
scipy: None
xarray: None
IPython: 5.3.0
sphinx: None
patsy: None
dateutil: 2.6.0
pytz: 2017.2
blosc: None
bottleneck: None
tables: None
numexpr: None
feather: None
matplotlib: None
openpyxl: 2.4.7
xlrd: None
xlwt: None
xlsxwriter: None
lxml: None
bs4: None
html5lib: 0.999999999
sqlalchemy: None
pymysql: 0.7.11.None
psycopg2: None
jinja2: 2.9.6
s3fs: None
pandas_gbq: None
pandas_datareader: None

</details>



Discussion:
I think that's what it's supposed to do, though.  From the [documentation](https://pandas.pydata.org/pandas-docs/stable/generated/pandas.DataFrame.update.html):

> Modify DataFrame in place using non-NA values from passed DataFrame.
some examples in the doc-string would be great for this. @lvphj want to do a PR ?
You're right. Sorry, somehow I missed that in the docs. Yes, I'll add some examples to the docs and send a PR.

Resolving patch:
diff --git a/pandas/core/frame.py b/pandas/core/frame.py
--- a/pandas/core/frame.py
+++ b/pandas/core/frame.py
@@ -4154,6 +4154,61 @@ def update(self, other, join='left', overwrite=True, filter_func=None,
         raise_conflict : boolean
             If True, will raise an error if the DataFrame and other both
             contain data in the same place.
+
+        Examples
+        --------
+        >>> df = pd.DataFrame({'A': [1, 2, 3],
+        ...                    'B': [400, 500, 600]})
+        >>> new_df = pd.DataFrame({'B': [4, 5, 6],
+        ...                        'C': [7, 8, 9]})
+        >>> df.update(new_df)
+        >>> df
+           A  B
+        0  1  4
+        1  2  5
+        2  3  6
+
+        >>> df = pd.DataFrame({'A': ['a', 'b', 'c'],
+        ...                    'B': ['x', 'y', 'z']})
+        >>> new_df = pd.DataFrame({'B': ['d', 'e', 'f', 'g', 'h', 'i']})
+        >>> df.update(new_df)
+        >>> df
+           A  B
+        0  a  d
+        1  b  e
+        2  c  f
+
+        >>> df = pd.DataFrame({'A': ['a', 'b', 'c'],
+        ...                    'B': ['x', 'y', 'z']})
+        >>> new_column = pd.Series(['d', 'e'], name='B', index=[0, 2])
+        >>> df.update(new_column)
+        >>> df
+           A  B
+        0  a  d
+        1  b  y
+        2  c  e
+        >>> df = pd.DataFrame({'A': ['a', 'b', 'c'],
+        ...                    'B': ['x', 'y', 'z']})
+        >>> new_df = pd.DataFrame({'B': ['d', 'e']}, index=[1, 2])
+        >>> df.update(new_df)
+        >>> df
+           A  B
+        0  a  x
+        1  b  d
+        2  c  e
+
+        If ``other`` contains NaNs the corresponding values are not updated
+        in the original dataframe.
+
+        >>> df = pd.DataFrame({'A': [1, 2, 3],
+        ...                    'B': [400, 500, 600]})
+        >>> new_df = pd.DataFrame({'B': [4, np.nan, 6]})
+        >>> df.update(new_df)
+        >>> df
+           A      B
+        0  1    4.0
+        1  2  500.0
+        2  3    6.0
         """
         import pandas.core.computation.expressions as expressions
         # TODO: Support other joins
diff --git a/pandas/core/series.py b/pandas/core/series.py
--- a/pandas/core/series.py
+++ b/pandas/core/series.py
@@ -1780,6 +1780,44 @@ def update(self, other):
         Parameters
         ----------
         other : Series
+
+        Examples
+        --------
+        >>> s = pd.Series([1, 2, 3])
+        >>> s.update(pd.Series([4, 5, 6]))
+        >>> s
+        0    4
+        1    5
+        2    6
+        dtype: int64
+
+        >>> s = pd.Series(['a', 'b', 'c'])
+        >>> s.update(pd.Series(['d', 'e'], index=[0, 2]))
+        >>> s
+        0    d
+        1    b
+        2    e
+        dtype: object
+
+        >>> s = pd.Series([1, 2, 3])
+        >>> s.update(pd.Series([4, 5, 6, 7, 8]))
+        >>> s
+        0    4
+        1    5
+        2    6
+        dtype: int64
+
+        If ``other`` contains NaNs the corresponding values are not updated
+        in the original Series.
+
+        >>> s = pd.Series([1, 2, 3])
+        >>> s.update(pd.Series([4, np.nan, 6]))
+        >>> s
+        0    4
+        1    2
+        2    6
+        dtype: int64
+
         """
         other = other.reindex_like(self)
         mask = notna(other)


Test patch: