将带有字典对象的 pandas 数据框转换为带有对象类型的 Polars 数据框

问题描述 投票:0回答:1

我有一个带有一列字典的 pandas 数据框。我想将其转换为 dtype

polars.Object
的极坐标数据框,它显然包装了任意 Python 对象。我不知道该怎么做。

考虑这段代码:

>>> df = pandas.DataFrame({ "the_column": [{ "key" : 123 }, { "foo" : 456 }, { "bar" : 789 }]})
>>> df
     the_column
0  {'key': 123}
1  {'foo': 456}
2  {'bar': 789}
>>> polars.from_pandas(df)
shape: (3, 1)
┌─────────────────┐
│ the_column      │
│ ---             │
│ struct[3]       │
╞═════════════════╡
│ {null,null,123} │
│ {null,456,null} │
│ {789,null,null} │
└─────────────────┘

如您所见,默认情况下,Polars 尝试将字典转换为箭头结构。这不是我想要的,因为每个对象的键都不相同。我希望它们保留为 Python 对象。

schema_overrides
功能做了一些事情,但也不是我想要的:

>>> polars.from_pandas(df, schema_overrides = {'the_column': polars.Object })
thread '<unnamed>' panicked at 'cannot convert object to arrow', /Users/runner/work/polars/polars/polars/polars-core/src/datatypes/dtype.rs:232:26
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/opt/homebrew/lib/python3.10/site-packages/polars/utils.py", line 498, in wrapper
  File "/opt/homebrew/lib/python3.10/site-packages/polars/utils.py", line 433, in wrapper
  File "/opt/homebrew/lib/python3.10/site-packages/polars/convert.py", line 486, in from_pandas
    include_index=include_index,
  File "/opt/homebrew/lib/python3.10/site-packages/polars/utils.py", line 433, in wrapper
  File "/opt/homebrew/lib/python3.10/site-packages/polars/internals/dataframe/frame.py", line 642, in _from_pandas
  File "/opt/homebrew/lib/python3.10/site-packages/polars/utils.py", line 433, in wrapper
  File "/opt/homebrew/lib/python3.10/site-packages/polars/internals/construction.py", line 1410, in pandas_to_pydf
  File "/opt/homebrew/lib/python3.10/site-packages/polars/internals/construction.py", line 1242, in arrow_to_pydf
    schema, schema_overrides=schema_overrides
  File "/opt/homebrew/lib/python3.10/site-packages/polars/internals/construction.py", line 577, in _post_apply_columns
    column_names,  # type: ignore[return-value]
pyo3_runtime.PanicException: cannot convert object to arrow

我怎样才能在这里完成我想要的事情?

python pandas dataframe python-polars
1个回答
2
投票

简短回答

你不知道。

更长的答案

Object
数据支持有限。在这里,您遇到了其中一个限制,因为 python 字典的集合不是 Arrow 标准中的数据类型,至少在没有大量自定义的情况下是这样。此外,对于一列 Python 字典,无论如何,您都无法以高性能的方式对数据“做”很多事情。

如果您想使用极坐标(而且您应该使用极坐标,这非常酷!)那么我建议您最好将数据重新构造为能够与(基于列的)很好地配合的格式Polars 可以毫无问题地处理箭头数据结构。

例如,在您的情况下,每个 python 字典中只有一个键值对。假设这始终是正确的,那么您可以创建包含键的列

"key"
,以及保存值的另一列
"value"
。两种结构之间的信息丢失完全为零,但在建议的两列版本中,您现在可以对生成的框架执行任何您喜欢的操作。

(
    pl.DataFrame(
        {
            "the_column": pl.Series(
                [
                    {"key": 123},
                    {"foo": 456},
                    {"bar": 789},
                ],
                dtype=pl.Object
            ),
        }
    )
    .select(
        pl.col("the_column")
        .map_elements(lambda x: list(x.keys()))
        .list.get(0)
        .alias("key"),
        pl.col("the_column")
        .map_elements(lambda x: list(x.values()))
        .list.get(0)
        .alias("value"),
    )
)
shape: (3, 2)
┌─────┬───────┐
│ key ┆ value │
│ --- ┆ ---   │
│ str ┆ i64   │
╞═════╪═══════╡
│ key ┆ 123   │
│ foo ┆ 456   │
│ bar ┆ 789   │
└─────┴───────┘

或类似的东西,具体取决于您的实际数据。

© www.soinside.com 2019 - 2024. All rights reserved.