Repository: pandas-dev/pandas

Issue:
pivot_table drops columns for aggregate functions that return all None, even if dropna=False
`pivot_table` drops columns for aggregate functions that return all `None`, even if `dropna=False`. I'm using `pandas: 0.23.3` and the full output of `pd.show_versions()` is posted at the end of this comment. https://github.com/pandas-dev/pandas/issues/21969 seems to be related.

#### Code Sample

```python
import pandas as pd
# pd.__version__ = '0.23.3'

# create sample dataframe to be pivoted
df = pd.DataFrame({'fruit':['apple','orange','peach','apple','peach'], 
    'size': [1,1.5,1,2,1],
    'taste': [7,8,6,6,10]})

# create three aggregate functions, one which returns only None
def return_one(x): 
    return 1

def return_sum(x):
    return sum(x)

def return_none(x):
    return None 

# reshape the dataframe
df2 = pd.pivot_table(df, columns='fruit', 
               aggfunc=[return_sum,return_none,return_one], 
               dropna=False)

# df2 does not include the output 
# of return_none, which is unexpected

#      return_sum              return_one             
# fruit      apple orange peach      apple orange peach
# size         3.0    1.5   2.0        1.0    1.0   1.0
# taste       13.0    8.0  16.0        1.0    1.0   1.0
```
#### Problem description

The [`dropna` argument](https://pandas.pydata.org/pandas-docs/version/0.23/generated/pandas.pivot_table.html) of `pivot_table` is `True` by default, meaning that the default output of `pivot_table` will not include "columns whose entries are all NaN".

If `dropna` is set to False, I would expect the resulting dataframe to include columns whose entries are all NaN (or None). This is not the case. As shown in the example, the columns are dropped even if `dropna=False`.

#### Expected Output

```
      return_sum             return_none              return_one             
fruit      apple orange peach      apple orange peach      apple orange peach
size         3.0    1.5   2.0       None   None  None       1.0    1.0   1.0
taste       13.0    8.0  16.0       None   None  None       1.0    1.0   1.0
```

#### Output of ``pd.show_versions()``

<details>

INSTALLED VERSIONS
------------------
commit: None
python: 3.6.5.final.0
python-bits: 64
OS: Darwin
OS-release: 17.7.0
machine: x86_64
processor: i386
byteorder: little
LC_ALL: None
LANG: en_US.UTF-8
LOCALE: en_US.UTF-8

pandas: 0.23.3
pytest: 3.3.2
pip: 18.0
setuptools: 39.0.1
Cython: 0.28.4
numpy: 1.14.0
scipy: 1.0.0
pyarrow: None
xarray: None
IPython: 6.2.1
sphinx: 1.6.7
patsy: 0.5.0
dateutil: 2.7.3
pytz: 2018.4
blosc: None
bottleneck: None
tables: None
numexpr: None
feather: None
matplotlib: 2.0.2
openpyxl: None
xlrd: 1.1.0
xlwt: None
xlsxwriter: 1.0.5
lxml: None
bs4: 4.6.0
html5lib: 1.0.1
sqlalchemy: 1.2.6
pymysql: None
psycopg2: 2.7.4 (dt dec pq3 ext lo64)
jinja2: 2.10
s3fs: None
fastparquet: None
pandas_gbq: None
pandas_datareader: None

</details>



Discussion:

Resolving patch:
diff --git a/pandas/core/reshape/pivot.py b/pandas/core/reshape/pivot.py
--- a/pandas/core/reshape/pivot.py
+++ b/pandas/core/reshape/pivot.py
@@ -34,7 +34,8 @@ def pivot_table(data, values=None, index=None, columns=None, aggfunc='mean',
             table = pivot_table(data, values=values, index=index,
                                 columns=columns,
                                 fill_value=fill_value, aggfunc=func,
-                                margins=margins, margins_name=margins_name)
+                                margins=margins, dropna=dropna,
+                                margins_name=margins_name)
             pieces.append(table)
             keys.append(getattr(func, '__name__', func))
 


Test patch:
diff --git a/pandas/tests/reshape/test_pivot.py b/pandas/tests/reshape/test_pivot.py
--- a/pandas/tests/reshape/test_pivot.py
+++ b/pandas/tests/reshape/test_pivot.py
@@ -1288,6 +1288,55 @@ def test_pivot_number_of_levels_larger_than_int32(self):
             df.pivot_table(index='ind1', columns='ind2',
                            values='count', aggfunc='count')
 
+    def test_pivot_table_aggfunc_dropna(self, dropna):
+        # GH 22159
+        df = pd.DataFrame({'fruit': ['apple', 'peach', 'apple'],
+                           'size': [1, 1, 2],
+                           'taste': [7, 6, 6]})
+
+        def ret_one(x):
+            return 1
+
+        def ret_sum(x):
+            return sum(x)
+
+        def ret_none(x):
+            return np.nan
+
+        result = pd.pivot_table(df, columns='fruit',
+                                aggfunc=[ret_sum, ret_none, ret_one],
+                                dropna=dropna)
+
+        data = [[3, 1, np.nan, np.nan, 1, 1], [13, 6, np.nan, np.nan, 1, 1]]
+        col = pd.MultiIndex.from_product([['ret_sum', 'ret_none', 'ret_one'],
+                                         ['apple', 'peach']],
+                                         names=[None, 'fruit'])
+        expected = pd.DataFrame(data, index=['size', 'taste'], columns=col)
+
+        if dropna:
+            expected = expected.dropna(axis='columns')
+
+        tm.assert_frame_equal(result, expected)
+
+    def test_pivot_table_aggfunc_scalar_dropna(self, dropna):
+        # GH 22159
+        df = pd.DataFrame({'A': ['one', 'two', 'one'],
+                           'x': [3, np.nan, 2],
+                           'y': [1, np.nan, np.nan]})
+
+        result = pd.pivot_table(df, columns='A',
+                                aggfunc=np.mean,
+                                dropna=dropna)
+
+        data = [[2.5, np.nan], [1, np.nan]]
+        col = pd.Index(['one', 'two'], name='A')
+        expected = pd.DataFrame(data, index=['x', 'y'], columns=col)
+
+        if dropna:
+            expected = expected.dropna(axis='columns')
+
+        tm.assert_frame_equal(result, expected)
+
 
 class TestCrosstab(object):