提问人:vinnewbie 提问时间:11/18/2023 最后编辑:vinnewbie 更新时间:11/19/2023 访问量:61
如何将列表列表转换为具有 list[struct[n]] 类型列的极坐标数据帧?
How to convert a list of lists into a polars dataframe with a column of type list[struct[n]]?
问:
我有一个列表列表。每个单独的列表可能具有不同的长度。列表的每个元素都是元组。
list1 = [("a", 1), ("b", 2)]
list2 = [("c", 3), ("d", 4), ("e", 5)]
我想将它们全部组合到一个类型为 list[struct[2]] 的极性数据帧列中。
在打印数据帧时,我应该看到:
column_name
list[struct[2]]
[{"a",1}, {"b",2}]
[{"c",3}, {"d",4}, {"e",5}]
我所要做的就是使用下面的代码获取一列 struct[2]
list1 = ["a", "b", "c"]
list2 = [1, 2, 3]
df = pl.DataFrame({
"col1": list1,
"col2": list2
})
print (df)
dfs = df.select(pl.struct(pl.all()).alias("my_struct"))
print(dfs)
但这远不是我想要实现的目标
解决: 我使用以下代码解决了这个问题。看起来在极地结构与普通 python 中的字典具有相同的含义。
list1 = [("a", 1), ("b", 2)]
list2 = [("c", 3), ("d", 4), ("e", 5)]
list_of_lists = [list1, list2]
lofl_as_structs = [[dict(f1=pair[0], f2=pair[1]) for pair in lst] for lst in list_of_lists]
df = pl.DataFrame({"column_name": lofl_as_structs})
print(df)
结果:
shape: (2, 1)
┌─────────────────────────────┐
│ column_name │
│ --- │
│ list[struct[2]] │
╞═════════════════════════════╡
│ [{"a",1}, {"b",2}] │
│ [{"c",3}, {"d",4}, {"e",5}] │
└─────────────────────────────┘
附加问题:
我希望能够通过指定如下模式来稍微不同地执行上述操作:
df = pl.DataFrame(lofl_as_structs,schema={'column_name': pl.List(pl.Struct([pl.Field('f1', pl.Utf8), pl.Field('f2', pl.Int64)]))})
这给出了错误:
raise ShapeError("the row data does not match the number of columns")
polars.exceptions.ShapeError: the row data does not match the number of columns
有关在架构中更改哪些内容以消除此错误的任何线索。
答:
2赞
ignoring_gravity
11/18/2023
#1
假设您希望您的密钥是 ,您可以执行以下操作:'0', '1', ...
pl.Series(
[[{str(i): val for i, val in enumerate(j)} for j in lst] for lst in [list1, list2]]
)
这给了
Out[26]:
shape: (2,)
Series: '' [list[struct[2]]]
[
[{"a",1}, {"b",2}]
[{"c",3}, {"d",4}, {"e",5}]
]
3赞
jqurious
11/18/2023
#2
Polars 中的每列都有一个架构(“类型”)。
如果我们举个例子:{"a": 1}, {"b": 2}
df = pl.select(pl.concat_list(pl.struct(a=1), pl.struct(b=2)))
shape: (1, 1)
┌──────────────────────┐
│ a │
│ --- │
│ list[struct[2]] │
╞══════════════════════╡
│ [{1,null}, {null,2}] │ # [{"a": 1, b: None}, {"a": None: b: 2}]
└──────────────────────┘
Polars 将架构确定为:[ {"a": int, "b": int } ]
>>> df.schema
OrderedDict([('a', List(Struct([Field('a', Int32), Field('b', Int32)])))])
这基本上意味着:列中的每个结构都必须具有相同的字段名称。(键)
如果我们取你的起始列表:、、、、都是关键。a
b
c
d
e
list1 = [("a", 1), ("b", 2)]
list2 = [("c", 3), ("d", 4), ("e", 5)]
>>> dict(list1)
{'a': 1, 'b': 2}
>>> dict(list2)
{'c': 3, 'd': 4, 'e': 5}
如果你想要你所展示的结构,你实际上是在说你想要这个:
list1 = [{"key": "a", "value": 1}, {"key": "b", "value": 2}]
list2 = [{"key": "c", "value": 3}, {"key": "d", "value": 4}, {"key": "e", "value": 5}]
即,您的起始键必须成为实际值。
评论
0赞
vinnewbie
11/19/2023
不,“a”、“b”等与 1、2 等一样多。但是,由于我已经解决了这个问题,因此我将不胜感激,以帮助解决直接为此指定架构的新问题。谢谢!!
0赞
jqurious
11/19/2023
@vinnewbie 是的,我知道你想把它们用作“值”,但如果你看一下它们的输出,它们最终会成为结果字典中的“键”。这就是我试图表达的观点。dict(list1)
评论
[]
pl.DataFrame([lofl_as_structs], ...)