极坐标 Dataframe 中列表列表的Numpy数组

gab6jxml  于 2023-03-18  发布在  其他
关注(0)|答案(1)|浏览(202)

我正尝试将每个单元格中包含2D列表的 Dataframe 保存到 parquet 文件中。例如,我创建了一个包含2D列表的极坐标 Dataframe 。如表中所示,两列的dtype均为list[list[i64]]

┌─────────────────────┬─────────────────────┐
│ a                   ┆ b                   │
│ ---                 ┆ ---                 │
│ list[list[i64]]     ┆ list[list[i64]]     │
╞═════════════════════╪═════════════════════╡
│ [[1], [2], ... [4]] ┆ [[1], [2], ... [4]] │
│ [[1], [2], ... [4]] ┆ [[1], [2], ... [4]] │
└─────────────────────┴─────────────────────┘

在下面的代码中,我保存并读取了 Dataframe ,以检查是否确实可以将此 Dataframe 写入parquet文件或从parquet文件读取此 Dataframe 。
在这一步之后,我从 Dataframe 创建了一个numpy数组。这就是问题开始的地方。转换回一个polars Dataframe 仍然是可能的。尽管事实上两列的dtype现在都是一个对象。

┌─────────────────────────────────────┬─────────────────────────────────────┐
│ a                                   ┆ b                                   │
│ ---                                 ┆ ---                                 │
│ object                              ┆ object                              │
╞═════════════════════════════════════╪═════════════════════════════════════╡
│ [array([array([1], dtype=int64),... ┆ [array([array([1], dtype=int64),... │
│ [array([array([1], dtype=int64),... ┆ [array([array([1], dtype=int64),... │
└─────────────────────────────────────┴─────────────────────────────────────┘

现在,当我尝试将此 Dataframe 写入 parquet 文件时,弹出以下错误:Exception has occurred: PanicException cannot convert object to arrow。这确实是真的,因为dtype现在是对象。
我试过使用pl.from_numpy(),但这会影响阅读2D数组。我也试过强制转换,但从对象强制转换似乎不可能。用以前的dtype创建 Dataframe 似乎也不起作用。

**问题:**如何将此 Dataframe 写入parquet文件?最好使用dtype list[list[i64]]。我需要保留2D数组结构。

通过创建一个列表形式的结果,我可以写一个read,但当它是一个numpy数组时就不行了。

证明代码:

import polars as pl
import numpy as np

data = {
    "a": [[[[1],[2],[3],[4]], [[1],[2],[3],[4]]],
          [[[1],[2],[3],[4]], [[1],[2],[3],[4]]]], 
    "b": [[[[1],[2],[3],[4]], [[1],[2],[3],[4]]],
          [[[1],[2],[3],[4]], [[1],[2],[3],[4]]]]
}

df = pl.DataFrame(data)
df.write_parquet('test.parquet')

read_df = pl.read_parquet('test.parquet')
print(read_df)

证明结果:

┌─────────────────────────────────────┬─────────────────────────────────────┐
│ a                                   ┆ b                                   │
│ ---                                 ┆ ---                                 │
│ list[list[list[i64]]]               ┆ list[list[list[i64]]]               │
╞═════════════════════════════════════╪═════════════════════════════════════╡
│ [[[1], [2], ... [4]], [[1], [2],... ┆ [[[1], [2], ... [4]], [[1], [2],... │
│ [[[1], [2], ... [4]], [[1], [2],... ┆ [[[1], [2], ... [4]], [[1], [2],... │
└─────────────────────────────────────┴─────────────────────────────────────┘

样品代码:

import polars as pl
import numpy as np

data = {
    "a": [[[1],[2],[3],[4]], [[1],[2],[3],[4]]], 
    "b": [[[1],[2],[3],[4]], [[1],[2],[3],[4]]]
}

df = pl.DataFrame(data)
df.write_parquet('test.parquet')

read_df = pl.read_parquet('test.parquet')
print(read_df)

arr = np.dstack([read_df, df])

# schema={'a': list[list[pl.Int32]], 'b': list[list[pl.Int32]]}
combined = pl.DataFrame(arr.tolist(), schema=df.columns)
print(combined)

# combined.with_column(pl.col('a').cast(pl.List, strict=False).alias('a_list'))

combined.write_parquet('test_result.parquet')
xt0899hw

xt0899hw1#

也许有一种更简单的方法--但是你可以用explode/groupby来做“堆叠”:

frames = df, read_df

frames = (
   frame.with_columns(col=n)
        .with_row_count("row")
        .explode(pl.exclude("row", "col"))
   for n, frame in enumerate(frames)
)

combined = (
   pl.concat(frames)
     .groupby("row", "col", maintain_order=True)
     .agg(pl.all())
     .groupby("row", maintain_order=True)
     .agg(pl.exclude("col"))
     .drop("row")
)
shape: (2, 2)
┌─────────────────────────────────────┬─────────────────────────────────────┐
│ a                                   | b                                   │
│ ---                                 | ---                                 │
│ list[list[list[i64]]]               | list[list[list[i64]]]               │
╞═════════════════════════════════════╪═════════════════════════════════════╡
│ [[[1], [2], ... [4]], [[1], [2],... | [[[1], [2], ... [4]], [[1], [2],... │
│ [[[1], [2], ... [4]], [[1], [2],... | [[[1], [2], ... [4]], [[1], [2],... │
└─────────────────────────────────────┴─────────────────────────────────────┘

我认为.concat_list可能有用-但它们被合并了:
一个二个一个一个

相关问题