Polars是否支持从嵌套字典中创建数据框架?



我试图从字典(mainDict)中创建一个极地数据帧,其中mainDict的值之一是字典对象列表(nestedDicts)。当我尝试这样做时,我得到了一个我不知道含义的错误(见下文)。但是,pandas允许我使用mainDict创建一个数据框架。

我不确定是否我做错了什么,如果它是一个错误,或者如果这个操作只是不支持的极地。我不太担心找到一个变通方法,因为它应该是直截了当的(欢迎提出建议),但如果可能的话,我想这样做。

我在谷歌colab上的极地版本0.13.38(问题也发生在VScode本地,python版本3.9.6和windows 10)。下面是再现问题及其输出的代码示例。谢谢!

输入:

import polars as pl
import pandas as pd
template = {    'a':['A', 'AA'],
'b':['B', 'BB'],
'c':['C', 'CC'],
'd':[{'D1':'D2'}, {'DD1':'DD2'}]}
#create a dataframe using pandas
df_pandas = pd.DataFrame(template)
print(df_pandas)
#create a dataframe using polars
df_polars = pl.DataFrame(template)
print(df_polars)

输出:

a   b   c               d
0   A   B   C    {'D1': 'D2'}
1  AA  BB  CC  {'DD1': 'DD2'}
---------------------------------------------------------------------------
ComputeError                              Traceback (most recent call last)
<ipython-input-9-2abdc86d91da> in <module>()
12 
13 #create a dataframe using polars
---> 14 df_polars = pl.DataFrame(template)
15 print(df_polars)
3 frames
/usr/local/lib/python3.7/dist-packages/polars/internals/frame.py in __init__(self, data, columns, orient)
300 
301         elif isinstance(data, dict):
--> 302             self._df = dict_to_pydf(data, columns=columns)
303 
304         elif isinstance(data, np.ndarray):
/usr/local/lib/python3.7/dist-packages/polars/internals/construction.py in dict_to_pydf(data, columns)
400         return PyDataFrame(data_series)
401     # fast path
--> 402     return PyDataFrame.read_dict(data)
403 
404 
/usr/local/lib/python3.7/dist-packages/polars/internals/series.py in __init__(self, name, values, dtype, strict, nan_to_null)
225                 self._s = self.cast(dtype, strict=True)._s
226         elif isinstance(values, Sequence):
--> 227             self._s = sequence_to_pyseries(name, values, dtype=dtype, strict=strict)
228         elif _PANDAS_AVAILABLE and isinstance(values, (pd.Series, pd.DatetimeIndex)):
229             self._s = pandas_to_pyseries(name, values)
/usr/local/lib/python3.7/dist-packages/polars/internals/construction.py in sequence_to_pyseries(name, values, dtype, strict)
241             if constructor == PySeries.new_object:
242                 try:
--> 243                     return PySeries.new_from_anyvalues(name, values)
244                 # raised if we cannot convert to Wrap<AnyValue>
245                 except RuntimeError:
ComputeError: struct orders must remain the same

您收到的错误是因为您的字典列表不符合polar中Seriesstruct的期望。更具体地说,您的两个字典{'D1':'D2'}{'DD1':'DD2'}在polar中被映射到两种不同类型的结构体,因此对于包含在同一个Series中是不兼容的。

我首先需要解释结构…

高偏振星:结构体

在polar中,字典被映射到称为struct的东西。结构体是一个有序的命名,类型化数据的集合。(在这方面,结构体很像只有一行的PolarsDataFrame。)

在struct中:

  1. 每个字段必须有一个唯一的字段名
  2. 每个字段都有一个数据类型

极性:将字典映射到结构

当字典映射到结构体时(例如,在DataFrame构造函数中),字典中的每个键都映射到结构体中的字段名,并将相应的字典值赋给结构体中该字段的值。

同样,键在字典中的顺序也很重要:struct字段的创建顺序与字典中的键的顺序相同。在Python中,很容易忘记字典中的键是有序的。

在3.7版更改:字典顺序保证为插入顺序。此行为是CPython从3.6开始的实现细节。

极性:结构体的系列/列表

这就是你的输入在polar中遇到麻烦的地方。只有满足以下条件,一个结构的集合才能包含在同一个Series中:

  1. 结构体具有相同数量的字段
  2. 字段名称相同
  3. 字段顺序相同
  4. 每个结构体的每个字段的数据类型是相同的。

在您的输入中,{'D1':'D2'}被映射到一个结构体,其中一个字段的字段名为"D1"值为"d2"。但是,{'DD1':'DD2'}被映射到一个结构体,其中有一个字段名为";dd1 &;"和value "DD2"。因此,结果结构不兼容,不能包含在同一个Series中。它们的字段名不匹配。

在本例中,北极星是far比Pandas更挑剔,后者允许具有任意键值对的字典出现在同一列中。

总的来说,你会发现polar在数据结构和数据类型方面比Pandas更加固执己见。(部分原因与性能有关。)

工作区

您的示例的一个解决方法是更改字典,使它们以相同的顺序包含相同的键。例如:

template = {
"a": ["A", "AA"],
"b": ["B", "BB"],
"c": ["C", "CC"],
"d": [{"D1": "D2", "DD1": None}, {"D1": None, "DD1": "DD2"}],
}
pl.DataFrame(template)
shape: (2, 4)
┌─────┬─────┬─────┬──────────────┐
│ a   ┆ b   ┆ c   ┆ d            │
│ --- ┆ --- ┆ --- ┆ ---          │
│ str ┆ str ┆ str ┆ struct[2]    │
╞═════╪═════╪═════╪══════════════╡
│ A   ┆ B   ┆ C   ┆ {"D2",null}  │
├╌╌╌╌╌┼╌╌╌╌╌┼╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌╌╌╌╌┤
│ AA  ┆ BB  ┆ CC  ┆ {null,"DD2"} │
└─────┴─────┴─────┴──────────────┘

另一个简单的解决方法是首先将数据导入Pandas,然后将Pandas DataFrame导入polar。导入过程将为您完成这项工作。

template = {
"a": ["A", "AA"],
"b": ["B", "BB"],
"c": ["C", "CC"],
"d": [{"D1": "D2"}, {"DD1": "DD2"}],
}
pl.DataFrame(pd.DataFrame(template))
>>> pl.DataFrame(pd.DataFrame(template))
shape: (2, 4)
┌─────┬─────┬─────┬──────────────┐
│ a   ┆ b   ┆ c   ┆ d            │
│ --- ┆ --- ┆ --- ┆ ---          │
│ str ┆ str ┆ str ┆ struct[2]    │
╞═════╪═════╪═════╪══════════════╡
│ A   ┆ B   ┆ C   ┆ {"D2",null}  │
├╌╌╌╌╌┼╌╌╌╌╌┼╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌╌╌╌╌┤
│ AA  ┆ BB  ┆ CC  ┆ {null,"DD2"} │
└─────┴─────┴─────┴──────────────┘

可能有其他解决方法,但这取决于您的具体数据和需求。

相关内容

  • 没有找到相关文章

最新更新