我遇到了一个看似推理的问题。如果我有一个结构列表(由 4 种不同数据类型的字段组成),则 Polars 仅在列表的前 25 项中出现值时才会解析字段。
我正在将 json 数据加载到框架中(首先通过 json.loads 转换为 dict)。数据是严重嵌套的。 问题是,有一列是结构列表。我在加载时将预定义的架构传递给 DataFrame 类。所以相关字段看起来像这样:
{
"attributes": pl.List(pl.Struct({
"stringValue": pl.String,
"boolValue": pl.Boolean,
"intValue": pl.Int64,
"doubleValue": pl.Float64
}))}
列表中的每个项目仅出现 1 个值类型。例如,如果 string 和 bool 类型出现在前 25 个项目中,则它们将在其余项目中正确解析。例如,如果 int 类型出现在第 25 项之后,它将返回 None。
这是预期的行为吗? 有什么方法可以配置推断的项目数量吗? 有解决办法吗?
我尝试了各种模式定义,
infer_schema_length
,使用read_json
与pl.DataFrame
。如果我使用测试数据并操纵列表中项目的顺序,我就可以让它工作。问题是我无法控制列表字段中项目的顺序。
更新 示例:
import polars as pl
data_schema = {
"attributes": pl.List(pl.Struct({
"key": pl.String,
"value": pl.Struct({
"stringValue": pl.String,
"doubleValue": pl.Float64,
"boolValue": pl.Boolean,
"intValue": pl.Int64,
}),
})),
}
data = [
{
"attributes": [
{"key": "string1", "value": {"stringValue": "sv1"}},
{"key": "string2", "value": {"stringValue": "sv2"}},
{"key": "string3", "value": {"stringValue": "sv3"}},
{"key": "string4", "value": {"stringValue": "sv4"}},
{"key": "string5", "value": {"stringValue": "sv5"}},
{"key": "string6", "value": {"stringValue": "sv6"}},
{"key": "string7", "value": {"stringValue": "sv7"}},
{"key": "string8", "value": {"stringValue": "sv8"}},
{"key": "string9", "value": {"stringValue": "sv9"}},
{"key": "int1", "value": {"intValue": 1}},
{"key": "int2", "value": {"intValue": 2}},
{"key": "int3", "value": {"intValue": 3}},
{"key": "string10", "value": {"stringValue": "sv10"}},
{"key": "string11", "value": {"stringValue": "sv11"}},
{"key": "string12", "value": {"stringValue": "sv12"}},
{"key": "string13", "value": {"stringValue": "sv13"}},
{"key": "string14", "value": {"stringValue": "sv14"}},
{"key": "string15", "value": {"stringValue": "sv15"}},
{"key": "string16", "value": {"stringValue": "sv16"}},
{"key": "string17", "value": {"stringValue": "sv17"}},
{"key": "string18", "value": {"stringValue": "sv18"}},
{"key": "string19", "value": {"stringValue": "sv19"}},
{"key": "string20", "value": {"stringValue": "sv20"}},
{"key": "string21", "value": {"stringValue": "sv21"}},
{"key": "string22", "value": {"stringValue": "sv22"}},
{"key": "string23", "value": {"stringValue": "sv23"}},
{"key": "string24", "value": {"stringValue": "sv24"}},
{"key": "string25", "value": {"stringValue": "sv25"}},
{"key": "int4", "value": {"intValue": 4}},
{"key": "int5", "value": {"intValue": 5}},
{"key": "bool1", "value": {"boolValue": True}},
{"key": "bool2", "value": {"boolValue": False}},
{"key": "bool3", "value": {"boolValue": True}},
{"key": "double1", "value": {"doubleValue": 0.1}},
{"key": "double2", "value": {"doubleValue": 2.3}},
]
}
]
df = pl.DataFrame(data, schema=data_schema)
df.rows()
输出:
[([{'key': 'string1',
'value': {'stringValue': 'sv1',
'doubleValue': None,
'boolValue': None,
'intValue': None}},
{'key': 'string2',
'value': {'stringValue': 'sv2',
'doubleValue': None,
'boolValue': None,
'intValue': None}},
{'key': 'string3',
'value': {'stringValue': 'sv3',
'doubleValue': None,
'boolValue': None,
'intValue': None}},
{'key': 'string4',
'value': {'stringValue': 'sv4',
'doubleValue': None,
'boolValue': None,
'intValue': None}},
{'key': 'string5',
'value': {'stringValue': 'sv5',
'doubleValue': None,
'boolValue': None,
'intValue': None}},
{'key': 'string6',
'value': {'stringValue': 'sv6',
'doubleValue': None,
'boolValue': None,
'intValue': None}},
{'key': 'string7',
'value': {'stringValue': 'sv7',
'doubleValue': None,
'boolValue': None,
'intValue': None}},
{'key': 'string8',
'value': {'stringValue': 'sv8',
'doubleValue': None,
'boolValue': None,
'intValue': None}},
{'key': 'string9',
'value': {'stringValue': 'sv9',
'doubleValue': None,
'boolValue': None,
'intValue': None}},
{'key': 'int1',
'value': {'stringValue': None,
'doubleValue': None,
'boolValue': None,
'intValue': 1}},
{'key': 'int2',
'value': {'stringValue': None,
'doubleValue': None,
'boolValue': None,
'intValue': 2}},
{'key': 'int3',
'value': {'stringValue': None,
'doubleValue': None,
'boolValue': None,
'intValue': 3}},
{'key': 'string10',
'value': {'stringValue': 'sv10',
'doubleValue': None,
'boolValue': None,
'intValue': None}},
{'key': 'string11',
'value': {'stringValue': 'sv11',
'doubleValue': None,
'boolValue': None,
'intValue': None}},
{'key': 'string12',
'value': {'stringValue': 'sv12',
'doubleValue': None,
'boolValue': None,
'intValue': None}},
{'key': 'string13',
'value': {'stringValue': 'sv13',
'doubleValue': None,
'boolValue': None,
'intValue': None}},
{'key': 'string14',
'value': {'stringValue': 'sv14',
'doubleValue': None,
'boolValue': None,
'intValue': None}},
{'key': 'string15',
'value': {'stringValue': 'sv15',
'doubleValue': None,
'boolValue': None,
'intValue': None}},
{'key': 'string16',
'value': {'stringValue': 'sv16',
'doubleValue': None,
'boolValue': None,
'intValue': None}},
{'key': 'string17',
'value': {'stringValue': 'sv17',
'doubleValue': None,
'boolValue': None,
'intValue': None}},
{'key': 'string18',
'value': {'stringValue': 'sv18',
'doubleValue': None,
'boolValue': None,
'intValue': None}},
{'key': 'string19',
'value': {'stringValue': 'sv19',
'doubleValue': None,
'boolValue': None,
'intValue': None}},
{'key': 'string20',
'value': {'stringValue': 'sv20',
'doubleValue': None,
'boolValue': None,
'intValue': None}},
{'key': 'string21',
'value': {'stringValue': 'sv21',
'doubleValue': None,
'boolValue': None,
'intValue': None}},
{'key': 'string22',
'value': {'stringValue': 'sv22',
'doubleValue': None,
'boolValue': None,
'intValue': None}},
{'key': 'string23',
'value': {'stringValue': 'sv23',
'doubleValue': None,
'boolValue': None,
'intValue': None}},
{'key': 'string24',
'value': {'stringValue': 'sv24',
'doubleValue': None,
'boolValue': None,
'intValue': None}},
{'key': 'string25',
'value': {'stringValue': 'sv25',
'doubleValue': None,
'boolValue': None,
'intValue': None}},
{'key': 'int4',
'value': {'stringValue': None,
'doubleValue': None,
'boolValue': None,
'intValue': 4}},
{'key': 'int5',
'value': {'stringValue': None,
'doubleValue': None,
'boolValue': None,
'intValue': 5}},
{'key': 'bool1',
'value': {'stringValue': None,
'doubleValue': None,
'boolValue': None,
'intValue': None}},
{'key': 'bool2',
'value': {'stringValue': None,
'doubleValue': None,
'boolValue': None,
'intValue': None}},
{'key': 'bool3',
'value': {'stringValue': None,
'doubleValue': None,
'boolValue': None,
'intValue': None}},
{'key': 'double1',
'value': {'stringValue': None,
'doubleValue': None,
'boolValue': None,
'intValue': None}},
{'key': 'double2',
'value': {'stringValue': None,
'doubleValue': None,
'boolValue': None,
'intValue': None}}],)]
如果我获取您的数据,然后将其保存到 json 文件,那么即使我没有显式设置模式,极化似乎也可以使用
pl.read_json
正确推断所有字段
说清楚我在做什么
with open('blah.json','w') as ff:
ff.write(json.dumps(data))
df=pl.read_json("blah.json")
确认它没有忽略我刚刚做的任何事情
(
df
.explode('attributes')
.unnest('attributes')
.unnest('value')
.filter(pl.all_horizontal(pl.exclude('key').is_null()))
)
过滤器返回至少有一个值为空的任何行。它不返回任何内容,这意味着它正在工作。
我在使用
pl.DataFrame
构造函数时遇到了同样的问题。这是一个错误,但如果你的最终源是一个 json 文件,那么即使这个错误不存在,使用 Polars 方法也会更好。