如何在Polars中通过循环重复列表生成新列(实现R中自动循环赋值的效果)
如何在Polars中通过循环重复列表生成新列(实现R中自动循环赋值的效果)
我明白你想要的效果啦——就是像R里那样,给DataFrame添加一个自动循环["lat", "lon"]的type列,对应每个地址的经纬度行。Polars不像R会自动循环短向量来匹配DataFrame长度,不过咱们有几种明确的方法可以实现这个需求,我给你一步步讲:
首先先看你的数据情况,d1是d0explode后的结果,有4行,每个地址对应两行坐标,现在要给这两行分别标上lat和lon。
方法一:显式循环序列(最贴近R的自动循环逻辑)
Polars的Series有个cycle()方法可以让序列无限循环,再用take(pl.count())取和DataFrame行数一样多的元素,完美模拟R的自动循环:
d1 = d1.with_columns( type=pl.Series(["lat", "lon"]).cycle().take(pl.count()) )
这个方法不管你的DataFrame有多少行(只要是2的倍数),都能自动重复lat、lon的顺序。
方法二:按地址分组分配(更贴合你的数据结构)
因为你的数据是每个地址对应两行坐标,咱们可以按adresse分组,给组内第一行标lat,第二行标lon:
d1 = d1.with_columns( type=pl.when(pl.row_number() == 1) .then(pl.lit("lat")) .otherwise(pl.lit("lon")) .over("adresse") )
这个方法更稳妥,哪怕后续某个地址的坐标行数有变化(当然你这里都是两行),也能保证每个地址的第一行是纬度,第二行是经度。
方法三:用行号取模判断
通过生成行号序列,对2取模,偶数行(从0开始)标lat,奇数行标lon:
d1 = d1.with_columns( type=pl.when(pl.int_range(0, pl.count()) % 2 == 0) .then("lat") .otherwise("lon") )
这个方法简单直接,适合整个DataFrame严格按lat、lon交替的场景。
为什么你之前的尝试没成功?
- 第一次用
pl.Series(["1","2"])时,Polars不会自动循环短向量,它要求新列长度必须和DataFrame行数一致,所以抛出了ShapeError; - 第二次用cross join是做笛卡尔积,会把每个行和
["1","2"]都配对,所以生成了8行,这显然不是你想要的结果。
完整代码示例
把方法整合进去,运行后就能得到你想要的结果:
import polars as pl d0 = pl.DataFrame( { "adresse": ["place 1", "place 2"], "coord": [[48.943837, 2.387917], [37.843837, 6.387917]], } ) d1 = d0.explode("coord") # 选一个你喜欢的方法添加type列 d1 = d1.with_columns( type=pl.Series(["lat", "lon"]).cycle().take(pl.count()) ) print(d1)
运行后输出的结果就是:
| adresse | coord | type |
|---|---|---|
| place 1 | 48.943837 | lat |
| place 1 | 2.387917 | lon |
| place 2 | 37.843837 | lat |
| place 2 | 6.387917 | lon |
完全符合你想要的表格样式~
备注:内容来源于stack exchange,提问作者Samuel Allain
相关产品推荐
相关产品推荐

