Repository: pandas-dev/pandas
Pull request: DOC: Update to docstring of DataFrame(dtype) (#14764)
 - [ ] closes #14764 
 - [ ] tests added / passed
 - [ ] passes ``git diff upstream/master --name-only -- '*.py' | flake8 --diff``
 - [ ] whatsnew entry


Problem statement:
DOC: pd.DataFrame(dtype) arg cannot be list, dict, Series. And None will infer wider type than necessary.
#### Code Sample, a copy-pastable example if possible

```python

# This is a DOCbug simply to document what pd.DataFrame(dtype) currently does.
# It is non-obvious to new users, gives non-obvious error messages, and also behaves differently to read_csv(dtype)

# a) Leaving dtype=None in constructor will infer a wider type than necessary
df_cols = {'year':np.int32, 'month':np.int8}
df = pd.DataFrame(columns=df_cols.keys(), dtype=None, index=range(10), data=-1)
>>> df.dtypes
month    int64
year     int64

# b) The doc doesn't explicitly say a list/dict/Series/array-like is not allowed (and if you
# pass in one the error is not very friendly). Also behaves differently to read_csv(dtype)
df = pd.DataFrame(columns=df_cols.keys(), dtype=np.int32, index=range(10), data=-1)
# df.dtypes shows they're all np.int32
# Fix up dtypes after declaration
for col,coltype in df_cols.items():
    df[col] = df[col].astype(coltype) 

```
#### Problem description

The DataFrame() doc doesn't explicitly say a list/dict/Series/array-like is not allowed (and if you pass in one the error is not very friendly). Also behaves differently to read_csv(dtype).
Leaving dtype=None in constructor will infer a wider type than necessary.
So in general you either set dtype=widest_necessary_type, or dtype=None and then manually fix them up after declaration, by casting with `astype()`

#### Expected Output

#### Output of ``pd.show_versions()``

<details>
python: 2.7.10.final.0
python-bits: 64
machine: x86_64
processor: i386
byteorder: little
pandas: 0.19.1
numpy: 1.11.2
scipy: 0.18.1
</details>

Hints from issue discussion:
repro for the error case
```python
df = pd.DataFrame(columns=['year', 'month'], 
                  dtype={'year': 'int32', 'month': 'int8'},
                  index=range(10), data=-1)
```

I could see an argument for supporting this, consistent with #13375
To be clear, I'm only asking for the documentation to reflect what currently happens. It's pretty confusing. We can live with fixing-up the dtypes after the df is declared; it would be good to document that workaround.
this is a (partial) duplicate of: https://github.com/pandas-dev/pandas/issues/4464 (which is the actual impl issue). No objections to clarifying the doc-string.
I would like to do this but I am not exactly sure what to do. Should I copy paste the example given by @smcinerney  in docstring of DataFrame class in pandas/core/frame.py ?
@patniharshit well, the idea is to create a nice-example / expl in the doc-string. so you can certainly start with that.
Looks like this issue got dropped. Happy to see if i can take a stab at this now. If anyone is at pycon sprints, happy to pair!
Ok added an example in the docstring. Would welcome feedback about its usefulness!

Commit message: Adding some more documentation on dataframe with regards to dtype

Patch to review:
diff --git a/pandas/core/frame.py b/pandas/core/frame.py
index 78a369761afc1..02404d7235031 100644
--- a/pandas/core/frame.py
+++ b/pandas/core/frame.py
@@ -241,17 +241,52 @@ class DataFrame(NDFrame):
         Column labels to use for resulting frame. Will default to
         np.arange(n) if no column labels are provided
     dtype : dtype, default None
-        Data type to force, otherwise infer
+        Data type to force. Only a single dtype is allowed. If None, infer
     copy : boolean, default False
         Copy data from inputs. Only affects DataFrame / 2d ndarray input
 
     Examples
     --------
-    >>> d = {'col1': ts1, 'col2': ts2}
-    >>> df = DataFrame(data=d, index=index)
-    >>> df2 = DataFrame(np.random.randn(10, 5))
-    >>> df3 = DataFrame(np.random.randn(10, 5),
+    Constructing DataFrame from a dictionary.
+
+    >>> d = {'col1': [1, 2], 'col2': [1, 2]}
+    >>> df = DataFrame(data=d)
+    >>> df
+        col1 col2
+    0   1    3
+    1   2    4
+
+    Notice that the inferred dtype is int64.
+
+    >>> df.dtypes
+    col1    int64
+    col2    int64
+    dtype: object
+
+    To enforce a single dtype:
+
+    >>> df = DataFrame(data=d, dtype=np.int8)
+    >>> df.dtypes
+    col1    int8
+    col2    int8
+    dtype: object
+
+    Constructing DataFrame from numpy ndarray:
+
+    >>> df2 = DataFrame(np.random.randn(10, 5),
     ...                 columns=['a', 'b', 'c', 'd', 'e'])
+    >>> df2
+        a           b           c           d           e
+    0   -0.783492   0.563675    -0.864924   0.391128    0.353971
+    1   1.254319    0.375264    0.592395    -0.573814   0.093112
+    2   -0.548918   0.334120    0.263741    0.007451    0.536851
+    3   -1.266109   0.472464    0.605991    0.183181    1.605140
+    4   -0.136033   -1.540123   -0.625398   -1.113922   -0.314596
+    5   0.497200    -0.793684   -1.077530   0.015950    1.194512
+    6   0.074891    -0.356493   1.094723    -0.695969   -0.318360
+    7   0.507182    -1.311427   -0.479544   -0.825982   -1.013853
+    8   -0.379124   -1.314563   -0.824940   0.587772    1.334155
+    9   0.389357    -1.399791   -1.498242   -0.312420   0.533206
 
     See also
     --------


Code review comments:
diff_hunk: @@ -241,17 +241,52 @@ class DataFrame(NDFrame):
         Column labels to use for resulting frame. Will default to
         np.arange(n) if no column labels are provided
     dtype : dtype, default None
-        Data type to force, otherwise infer
+        Data type to force. Only a single dtype is allowed. If None, infer
     copy : boolean, default False
         Copy data from inputs. Only affects DataFrame / 2d ndarray input
 
     Examples
     --------
-    >>> d = {'col1': ts1, 'col2': ts2}
-    >>> df = DataFrame(data=d, index=index)
-    >>> df2 = DataFrame(np.random.randn(10, 5))
-    >>> df3 = DataFrame(np.random.randn(10, 5),
+    Constructing DataFrame from a dictionary.
+
+    >>> d = {'col1': [1, 2], 'col2': [1, 2]}
+    >>> df = DataFrame(data=d)
+    >>> df
+        col1 col2
+    0   1    3
+    1   2    4
+
+    Notice that the inferred dtype is int64.
+
+    >>> df.dtypes
+    col1    int64
+    col2    int64
+    dtype: object
+
+    To enforce a single dtype:
+
+    >>> df = DataFrame(data=d, dtype=np.int8)
+    >>> df.dtypes
+    col1    int8
+    col2    int8
+    dtype: object
+
+    Constructing DataFrame from numpy ndarray:
+
+    >>> df2 = DataFrame(np.random.randn(10, 5),
     ...                 columns=['a', 'b', 'c', 'd', 'e'])
+    >>> df2
+        a           b           c           d           e
path: pandas/core/frame.py
text: @user1:
these are not lined up, something odd going on.

@author:
I think this is ok? It comes out looking like this when I generated
<img width="756" alt="screen shot 2017-05-24 at 4 18 57 pm" src="https://cloud.githubusercontent.com/assets/12398535/26429604/c1e08616-409c-11e7-9246-520b2764ac53.png">


@user1:
can you line up on the decimals. 

@author:
sure I'll just change the example to something easier with integers to take up less space anyway.