我正在try 将 BED12 format中的TSV文件转换为极点数据帧.我得到了两列编码为包含Coma分隔的整数的字符串.我的解决方案(简化)涉及通过 struct :

df = pl.DataFrame(
    {
        "chrom": ["1", "1", "2", "X"],
        "blockSizes": ["10,29,", "20,22,", "30,25,", "40,23,"],
        "blockStarts": ["0,50,", "0,45,", "0,60,", "0,70,"]
    })

df.with_columns(col("blockSizes").str.split(by=",")
.list.slice(0, 2)
.list.to_struct()
).unnest("blockSizes").with_columns(
    [
        col("field_0").cast(pl.Int32).alias("blockSizes_0"),
        col("field_1").cast(pl.Int32).alias("blockSizes_1"),
    ]
).drop(["field_0", "field_1"])

显然,我可以继续对blockStarts专栏做同样的事情,但我希望有一些更简单的方法.

非常感谢您的帮助

推荐答案

目前的方法可以修改:

  • .strip_chars()表示删除尾随逗号
  • .cast(pl.List(pl.Int32))一次投下所有的东西
  • 传递一个函数到.to_struct(fields=)以"动态地"重命名字段
cols = "blockSizes", "blockStarts"

(df.with_columns(
    pl.col(col)
      .str.strip_chars(",")
      .str.split(",")
      .cast(pl.List(pl.Int32))
      .list.to_struct(
         n_field_strategy = "max_width", 
         fields = lambda idx, col=col: f"{col}_{idx}"
      )
    for col in cols
 )
 .unnest(cols)
)
shape: (4, 5)
┌───────┬──────────────┬──────────────┬───────────────┬───────────────┐
│ chrom ┆ blockSizes_0 ┆ blockSizes_1 ┆ blockStarts_0 ┆ blockStarts_1 │
│ ---   ┆ ---          ┆ ---          ┆ ---           ┆ ---           │
│ str   ┆ i32          ┆ i32          ┆ i32           ┆ i32           │
╞═══════╪══════════════╪══════════════╪═══════════════╪═══════════════╡
│ 1     ┆ 10           ┆ 29           ┆ 0             ┆ 50            │
│ 1     ┆ 20           ┆ 22           ┆ 0             ┆ 45            │
│ 2     ┆ 30           ┆ 25           ┆ 0             ┆ 60            │
│ X     ┆ 40           ┆ 23           ┆ 0             ┆ 70            │
└───────┴──────────────┴──────────────┴───────────────┴───────────────┘

也许创建一个函数会让事情变得更整洁.

def csv_to_struct(col):
    expr = pl.col(col).str.strip_chars(",").str.split(",")
    expr = expr.cast(pl.List(pl.Int32))
    return expr.list.to_struct(
        n_field_strategy = "max_width", 
        fields = lambda idx: f"{col}_{idx}"
    )

cols = "blockSizes", "blockStarts"

df.with_columns(map(csv_to_struct, cols)).unnest(cols)

熔化/枢轴

另一种方法是使用.melt()+.pivot()

cols = "blockSizes", "blockStarts"

(df.with_row_count()
   .with_columns(
      pl.col(cols).str.strip_chars(",").str.split(",").cast(pl.List(int))
   )
   .explode(cols)
   .melt(["row_nr", "chrom"], variable_name="name")
   .with_columns(
      pl.format("{}_{}", "name", pl.col("row_nr").cum_count().over("row_nr", "name"))
   )
   .pivot("value", ["row_nr", "chrom"], "name")
)
shape: (4, 6)
┌────────┬───────┬──────────────┬──────────────┬───────────────┬───────────────┐
│ row_nr ┆ chrom ┆ blockSizes_0 ┆ blockSizes_1 ┆ blockStarts_0 ┆ blockStarts_1 │
│ ---    ┆ ---   ┆ ---          ┆ ---          ┆ ---           ┆ ---           │
│ u32    ┆ str   ┆ i64          ┆ i64          ┆ i64           ┆ i64           │
╞════════╪═══════╪══════════════╪══════════════╪═══════════════╪═══════════════╡
│ 0      ┆ 1     ┆ 10           ┆ 29           ┆ 0             ┆ 50            │
│ 1      ┆ 1     ┆ 20           ┆ 22           ┆ 0             ┆ 45            │
│ 2      ┆ 2     ┆ 30           ┆ 25           ┆ 0             ┆ 60            │
│ 3      ┆ X     ┆ 40           ┆ 23           ┆ 0             ┆ 70            │
└────────┴───────┴──────────────┴──────────────┴───────────────┴───────────────┘

Python相关问答推荐

Python中的负前瞻性regex遇到麻烦

即使在可见的情况下也不相互作用

将输入管道传输到正在运行的Python脚本中

如何使用根据其他值相似的列从列表中获取的中间值填充空NaN数据

使用groupby Pandas的一些操作

无法使用requests或Selenium抓取一个href链接

如何使用它?

对所有子图应用相同的轴格式

如何从数据库上传数据到html?

如何使Matplotlib标题以图形为中心,而图例框则以图形为中心

如何在TensorFlow中分类多个类

如何使用Numpy. stracards重新编写滚动和?

基于形状而非距离的两个numpy数组相似性

Python避免mypy在相互引用中从另一个类重定义类时失败

基于Scipy插值法的三次样条系数

如何将数据帧中的timedelta转换为datetime

如何在Great Table中处理inf和nans

用fft计算指数复和代替求和来模拟衍射?

如何在Polars中创建条件增量列?

VSCode Pylance假阳性(?)对ImportError的react