这是对之前回答过的问题的后续。
有一个像这样的大型数据框 df (在“SKU”列中列出)
| SKU | Count | Percent
|----------------------------------------------------------------------|-------|-------------|
| "('000000009100000749',)" | 110 | 0.029633621 |
| "('000000009100000749', '000000009100000776')" | 1 | 0.000269397 |
| "('000000009100000749', '000000009100000776', '000000009100002260')" | 1 | 0.000269397 |
| "('000000009100000749', '000000009100000777', '000000009100002260')" | 1 | 0.000269397 |
| "('000000009100000749', '000000009100000777', '000000009100002530')" | 1 | 0.000269397 |
需要将“SKU”列中的值替换为字典 df_unique 中的相应值,如下所示(请忽略下面的格式,它是一个字典):
skus str | 代码i64 |
---|---|
000000009100000749 | 1 |
000000009100000785 | 2 |
000000009100002088 | 3 |
我已经尝试过这段代码:
replacements = pl.col("SKU")
for old, new in df_unique.items():
replacements = replacements.str.replace_all(old, new)
df = df.select(replacements)
出现此错误: SchemaError:数据类型系列:列表(Utf8)!= Utf8
我尝试将列值更改为字符串,尽管我认为这是多余的,但同样的错误
df= df.with_column(
pl.col('SKU').apply(lambda row: [str(x) for x in row])
)
关于我做错了什么有什么指导吗?
如果您显示列的实际列表类型,将会有所帮助:
看起来你有“字符串化”元组,但并不完全清楚。
df = pl.DataFrame({
"SKU": [["000000009100000749"], ["000000009100000749", "000000009100000776"]]
})
sku_to_code = {
"000000009100000749": 1,
"000000009100000785": 2,
"000000009100002088": 3
}
>>> df
shape: (2, 1)
┌─────────────────────────────────────┐
│ SKU │
│ --- │
│ list[str] │
╞═════════════════════════════════════╡
│ ["000000009100000749"] │
│ ["000000009100000749", "00000000... │
└─────────────────────────────────────┘
.list.eval()
允许您在列表上运行表达式。
pl.element()
可以用来引用list.eval
里面的列表
replace_sku = pl.element()
for old, new in df_unique.items():
replace_sku = replace_sku.str.replace_all(old, str(new), literal=True)
df.select(pl.col("SKU").list.eval(replace_sku))
shape: (2, 1)
┌─────────────────────────────┐
│ SKU │
│ --- │
│ list[str] │
╞═════════════════════════════╡
│ ["1"] │
│ ["1", "000000009100000776"] │
└─────────────────────────────┘
列
SKU
具有 list[str]
dtype,但接下来您调用用于字符串的属性 .str
(此处:replacements.str.replace_all(old, new)
)。您应该将属性 .arr
与具有 list
dtype 和 相应方法的列一起使用。
您可以将下面的 sol-n 与
.apply()
一起使用,或者通过 jqurious 使用 sol-n,其工作速度更快(因为 .arr.eval()
允许并行运行所有表达式)
d = {"000000009100000749": 1, "000000009100000776": 2}
df = pl.DataFrame({
"SKU": [["000000009100000749", "000000009100000776"]]
})
df = df.with_column(
col("SKU").apply(
lambda row: [d[i] for i in row]
).alias("SKU_replaced")
)
来自 jqurious 和 glebcom 的两个解决方案都可以完美地解决所提出的问题。
我没有意识到 df_unique 是字典列表而不是字典,因此必须根据情况调整解决方案。这是 jqurious 稍微修改过的解决方案(更改循环以迭代 df_unique 字典列表中的元素):
replace_sku = pl.element()
for item in df_unique:
old = item['SKU']
new = item['code']
replace_sku = replace_sku.str.replace_all(old, str(new), literal=True)
df = df.select(pl.col("SKU").list.eval(replace_sku, parallel=True))