Support construction of a DataFrame from a Mapping
State: closed

This pull-request adds support for using a `Mapping` in the construction of a `DataFrame`.  By applying this change, the following Julia code will work.

```
julia> using PythonCall
julia> pd = pyimport("pandas")
julia> df = pd.DataFrame(Dict("a" => [1, 2, 3], "b" => [4, 5, 6]))
Python:
   b  a
0  4  1
1  5  2
2  6  3
```

I have confirmed that there is no performance degradation when constructing a `DataFrame` from a `dict`.

```
$ asv continuous -E virtualenv -b ^frame_ctor.FromDict origin/main HEAD
· Creating environments
· Discovering benchmarks
·· Uninstalling from virtualenv-py3.10-Cython3.0-jinja2-matplotlib-meson-meson-python-numba-numexpr-odfpy-openpyxl-pyarrow-python-build-scipy-sqlalchemy-tables-xlrd-xlsxwriter
·· Installing 684a22fb <support_mapping_in_dataframe> into virtualenv-py3.10-Cython3.0-jinja2-matplotlib-meson-meson-python-numba-numexpr-odfpy-openpyxl-pyarrow-python-build-scipy-sqlalchemy-tables-xlrd-xlsxwriter..
· Running 16 total benchmarks (2 commits * 1 environments * 8 benchmarks)
[ 0.00%] · For pandas commit 2aa155ae <main> (round 1/2):
[ 0.00%] ·· Building for virtualenv-py3.10-Cython3.0-jinja2-matplotlib-meson-meson-python-numba-numexpr-odfpy-openpyxl-pyarrow-python-build-scipy-sqlalchemy-tables-xlrd-xlsxwriter..
[ 0.00%] ·· Benchmarking virtualenv-py3.10-Cython3.0-jinja2-matplotlib-meson-meson-python-numba-numexpr-odfpy-openpyxl-pyarrow-python-build-scipy-sqlalchemy-tables-xlrd-xlsxwriter
[ 3.12%] ··· Running (frame_ctor.FromDicts.time_dict_of_categoricals--)........
[25.00%] · For pandas commit 684a22fb <support_mapping_in_dataframe> (round 1/2):
[25.00%] ·· Building for virtualenv-py3.10-Cython3.0-jinja2-matplotlib-meson-meson-python-numba-numexpr-odfpy-openpyxl-pyarrow-python-build-scipy-sqlalchemy-tables-xlrd-xlsxwriter..
[25.00%] ·· Benchmarking virtualenv-py3.10-Cython3.0-jinja2-matplotlib-meson-meson-python-numba-numexpr-odfpy-openpyxl-pyarrow-python-build-scipy-sqlalchemy-tables-xlrd-xlsxwriter
[28.12%] ··· Running (frame_ctor.FromDicts.time_dict_of_categoricals--)........
[50.00%] · For pandas commit 684a22fb <support_mapping_in_dataframe> (round 2/2):
[50.00%] ·· Benchmarking virtualenv-py3.10-Cython3.0-jinja2-matplotlib-meson-meson-python-numba-numexpr-odfpy-openpyxl-pyarrow-python-build-scipy-sqlalchemy-tables-xlrd-xlsxwriter
[53.12%] ··· frame_ctor.FromDicts.time_dict_of_categoricals                                327±8μs
[56.25%] ··· frame_ctor.FromDicts.time_list_of_dict                                    16.8±0.09ms
[59.38%] ··· frame_ctor.FromDicts.time_nested_dict                                      16.1±0.2ms
[62.50%] ··· frame_ctor.FromDicts.time_nested_dict_columns                              16.3±0.3ms
[65.62%] ··· frame_ctor.FromDicts.time_nested_dict_index                                13.2±0.1ms
[68.75%] ··· frame_ctor.FromDicts.time_nested_dict_index_columns                       12.9±0.08ms
[71.88%] ··· frame_ctor.FromDicts.time_nested_dict_int64                                29.1±0.1ms
[75.00%] ··· frame_ctor.FromDictwithTimestamp.time_dict_with_timestamp_offsets                  ok
[75.00%] ··· ======== ============
              offset
             -------- ------------
              <Nano>   7.97±0.1ms
              <Hour>   10.9±0.2ms
             ======== ============

[75.00%] · For pandas commit 2aa155ae <main> (round 2/2):
[75.00%] ·· Building for virtualenv-py3.10-Cython3.0-jinja2-matplotlib-meson-meson-python-numba-numexpr-odfpy-openpyxl-pyarrow-python-build-scipy-sqlalchemy-tables-xlrd-xlsxwriter..
[75.00%] ·· Benchmarking virtualenv-py3.10-Cython3.0-jinja2-matplotlib-meson-meson-python-numba-numexpr-odfpy-openpyxl-pyarrow-python-build-scipy-sqlalchemy-tables-xlrd-xlsxwriter
[78.12%] ··· frame_ctor.FromDicts.time_dict_of_categoricals                                330±2μs
[81.25%] ··· frame_ctor.FromDicts.time_list_of_dict                                     17.2±0.3ms
[84.38%] ··· frame_ctor.FromDicts.time_nested_dict                                     16.2±0.08ms
[87.50%] ··· frame_ctor.FromDicts.time_nested_dict_columns                              16.2±0.1ms
[90.62%] ··· frame_ctor.FromDicts.time_nested_dict_index                                13.2±0.2ms
[93.75%] ··· frame_ctor.FromDicts.time_nested_dict_index_columns                        13.5±0.2ms
[96.88%] ··· frame_ctor.FromDicts.time_nested_dict_int64                                29.7±0.3ms
[100.00%] ··· frame_ctor.FromDictwithTimestamp.time_dict_with_timestamp_offsets                  ok
[100.00%] ··· ======== =============
               offset
              -------- -------------
               <Nano>   8.16±0.07ms
               <Hour>   11.2±0.06ms
              ======== =============


BENCHMARKS NOT SIGNIFICANTLY CHANGED.
```

- [x] partially closes #58803 (only dataframe construction part)
- [ ] [Tests added and passed](https://pandas.pydata.org/pandas-docs/dev/development/contributing_codebase.html#writing-tests) if fixing a bug or adding a new feature
- [ ] All [code checks passed](https://pandas.pydata.org/pandas-docs/dev/development/contributing_codebase.html#pre-commit).
- [x] Added [type annotations](https://pandas.pydata.org/pandas-docs/dev/development/contributing_codebase.html#type-hints) to new arguments/methods/functions.
- [x] Added an entry in the latest `doc/source/whatsnew/vX.X.X.rst` file if fixing a bug or adding a new feature.


Labels:
name: Stale

Comments:
@twoertwein I noticed that creating a DataFrame from a Mapping of Mappings wasn't covered, so I added support for it. Could you please review this new change?

This pull request is stale because it has been open for thirty days with no activity. Please [update](https://pandas.pydata.org/pandas-docs/stable/development/contributing.html#updating-your-pull-request) and respond to this comment if you're still interested in working on this.
Thanks for the PR here, but let's centralize the discussion in the issue regarding whether pandas should make this more general. Closing for now, but we can reopen if there is consensus to change in the issue