Allows for more options when getting data from dictionaries.
State: closed

Fixes #9502 

See the [cloudtb tests/test_pandas.py](https://github.com/cloudformdesign/cloudtb/blob/f/pandas/tests/test_pandas.py) for more examples of use.

Once it is approved to go forward, I will add tests to show more about how
it can be used and make sure that every edge case if functional.

Has no effect on unit tests, although on my machine two were failing
before change, and several were skipped (and still fail after change). 
Please re-run unit tests.

Should have a negligible effect on performance, as it first checks whether
it should be used. If performance does end up being an issue, I
recommend adding a kwarg `flat=False` to the `DataFrame.from_dict`
method for speedups when the user knows their dictionary is flat
(i.e. is not nested)


Labels:
name: IO Data
description: IO issues that don't fit into a more specific label
name: API Design

Comments:
This looks interesting. Could you please provide explicit examples for each type of new structures this allows for parsing?

@cloudformdesign we cannot use external libraries like this. You will need to inline code in pandas.

I realized that,  it should be already done in the second commit

I'll work on examples tonight hopefully

@shoyer @jreback There are some examples in the new unit tests. Check them out.

Please note: the cloud_patch is not something that would be in there permanently. It is just to demonstrate that it works.

Something else that should be considered is a general design choice. This auto-detects whether the object is a dictionary of lists or a list of dictionaries. 

The list of dictionaries feature should maybe go in the `DataFrame.__init__` constructor itself since it already does lists of dictionaries. If that were the case, it could auto-detect `header` from the columns attribute. (i.e. the user could pass in `columns=nested_dictionary_that_has_all_the_right_keys` and it would convert it correctly) 

I'm not even sure why the whole thing couldn't go into the DataFrame constructor (and why `from_dict` is needed at all), but I'm sure you will have more opinions about that. To me, you could get rid of `from_dict` alltogether with a simple `isinstance(data, dict)` at the beginning of `DataFrame.__init__`

@cloudformdesign Could you share the `repr()` for the input and output you use in these examples?

For more info on the DataFrame constructor(s), please look at the relevant section of the docs: http://pandas.pydata.org/pandas-docs/stable/dsintro.html#dataframe

For nested dicts: (note: this is an ordered dict that is pprinted)

```
{'a': [0, 1, 2, 3, 4, 5],
 'b': [0, 1, 2, 3, 4, 5],
 'c': [0, 1, 2, 3, 4, 5],
 'd': [0, 1, 2, 3, 4, 5],
 'e': [0, 1, 2, 3, 4, 5],
 'f': [0, 1, 2, 3, 4, 5],
 'self': {'a': [0, 1, 2, 3, 4, 5],
          'b': [0, 1, 2, 3, 4, 5],
          'c': [0, 1, 2, 3, 4, 5],
          'd': [0, 1, 2, 3, 4, 5],
          'e': [0, 1, 2, 3, 4, 5],
          'f': [0, 1, 2, 3, 4, 5]}}
   a  b  c  d  e  f self               
                       a  b  c  d  e  f
0  0  0  0  0  0  0    0  0  0  0  0  0
1  1  1  1  1  1  1    1  1  1  1  1  1
2  2  2  2  2  2  2    2  2  2  2  2  2
3  3  3  3  3  3  3    3  3  3  3  3  3
4  4  4  4  4  4  4    4  4  4  4  4  4
5  5  5  5  5  5  5    5  5  5  5  5  5
```

For lists of dicts:  (same idea, the way mongo data is typically structured)

```
[
OrderedDict([('a', 0), ('b', 0), ('c', 0), ('d', 0), ('e', 0), ('f', 0), ('self', OrderedDict([('a', 0), ('b', 0), ('c', 0), ('d', 0), ('e', 0), ('f', 0)]))])
OrderedDict([('a', 1), ('b', 1), ('c', 1), ('d', 1), ('e', 1), ('f', 1), ('self', OrderedDict([('a', 1), ('b', 1), ('c', 1), ('d', 1), ('e', 1), ('f', 1)]))])
OrderedDict([('a', 2), ('b', 2), ('c', 2), ('d', 2), ('e', 2), ('f', 2), ('self', OrderedDict([('a', 2), ('b', 2), ('c', 2), ('d', 2), ('e', 2), ('f', 2)]))])
OrderedDict([('a', 3), ('b', 3), ('c', 3), ('d', 3), ('e', 3), ('f', 3), ('self', OrderedDict([('a', 3), ('b', 3), ('c', 3), ('d', 3), ('e', 3), ('f', 3)]))])
OrderedDict([('a', 4), ('b', 4), ('c', 4), ('d', 4), ('e', 4), ('f', 4), ('self', OrderedDict([('a', 4), ('b', 4), ('c', 4), ('d', 4), ('e', 4), ('f', 4)]))])
OrderedDict([('a', 5), ('b', 5), ('c', 5), ('d', 5), ('e', 5), ('f', 5), ('self', OrderedDict([('a', 5), ('b', 5), ('c', 5), ('d', 5), ('e', 5), ('f', 5)]))])
]
   a  b  c  d  e  f self               
                       a  b  c  d  e  f
0  0  0  0  0  0  0    0  0  0  0  0  0
1  1  1  1  1  1  1    1  1  1  1  1  1
2  2  2  2  2  2  2    2  2  2  2  2  2
3  3  3  3  3  3  3    3  3  3  3  3  3
4  4  4  4  4  4  4    4  4  4  4  4  4
5  5  5  5  5  5  5    5  5  5  5  5  5
```

closing pls reopen if/when updated