如何更改多级 index/column DataFrame 的 pyarrow table 列精度

how to change pyarrow table column precision for multi level index/column DataFrames

我有一个 pyarrow.Table 从 pandasDataFrame 创建的

    df = pd.DataFrame({"col1": [1.0, 2.0],  "col2": [2.3, 2.4]})
    df.columns = pd.MultiIndex.from_tuples([('a',100),('b',200)], names=('name', 'number'))
    df.index = pd.MultiIndex.from_tuples([('a',100),('b',200)], names=('name', 'number'))

    table = pa.Table.from_pandas(df)

原来的df有几千列几千行,值都是float64,所以我转成pyarrow就变成了doubleTable

如何将它们全部更改为 float32

我尝试了以下方法:

    schema = pa.schema([pa.field("('a',100)", pa.float32()),pa.field("('b',200)", pa.float32()),])
    table = pa.Table.from_pandas(df, schema=schema)

但是抱怨架构和数据框不匹配:KeyError: "name '('a',100)' present in the specified schema is not found in the columns or index"

首先将数据框转换为 table,然后更改架构,以便将每个 float64 都转换为 float32:

table = pa.Table.from_pandas(df)
schema = pa.schema(
    [
        pa.field(f.name, pa.float32() if f.type == pa.float64() else f.type) 
        for f in table.schema
    ]
)

table.cast(schema)

您可以将 table 转换为您需要的类型

table = pa.Table.from_pandas(df)
table = table.cast(pa.schema([("('a', '100')", pa.float32()), 
                              ("('b', '200')", pa.float32()), 
                              ("name", pa.string()), 
                              ("number", pa.string())]))

我怀疑您在使用 Pandas 多键索引时会找到一种方法来为 Table.from_pandas 提供工作模式。在这种情况下,列名是 tuple (('a', 100)) 但对于 Arrow schema 列名只能是字符串。因此,您将永远无法创建指向数据框具有的相同列名的模式。

这就是为什么之后转换有效的原因,因为 你做了一个箭头 table (因此所有列名都变成了字符串)你最终可以提供等于转换函数的列名。