gpt4 book ai didi

pandas - 如何在 polars DataFrame 中的每一列与该列的平均值之间轻松执行计算

转载 作者:行者123 更新时间:2023-12-01 22:58:02 27 4
gpt4 key购买 nike

环境

macos:             monterey
node: v18.1.0
nodejs-polars: 0.5.3

目标

用该列的平均值减去 polars DataFrame 中的每一列。

Pandas 解决方案

由于 DataFrame.sub(other, axis='columns', level=None, fill_value=None),在 pandas 中解决方案非常简洁。 other标量、序列、系列或 DataFrame:

df.sub(df.mean())
df - df.mean()

nodejs-polars解决方案

虽然在 nodejs-polars function 中,other 根据 sub: (other) => wrap("sub", prepareOtherArg 似乎只是一个 Series (其他).inner()).

1。准备数据

console.log(df)
┌─────────┬─────────┬─────────┬─────────┐
│ A ┆ B ┆ C ┆ D │
│ --- ┆ --- ┆ --- ┆ --- │
│ i64 ┆ i64 ┆ i64 ┆ i64 │
╞═════════╪═════════╪═════════╪═════════╡
│ 13520 ┆ -16 ┆ 384 ┆ 208 │
├╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌┤
│ 13472 ┆ -16 ┆ 384 ┆ 176 │
├╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌┤
│ 13456 ┆ -16 ┆ 368 ┆ 160 │
├╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌┤
│ 13472 ┆ -16 ┆ 368 ┆ 160 │
├╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌┤
│ 13472 ┆ -16 ┆ 352 ┆ 176 │
└─────────┴─────────┴─────────┴─────────┘
console.log(df.mean())
┌─────────┬─────────┬─────────┬─────────┐
│ A ┆ B ┆ C ┆ D │
│ --- ┆ --- ┆ --- ┆ --- │
│ f64 ┆ f64 ┆ f64 ┆ f64 │
╞═════════╪═════════╪═════════╪═════════╡
│ 13478.4 ┆ -16.0 ┆ 371.2 ┆ 176.0 │
└─────────┴─────────┴─────────┴─────────┘

2。第一次尝试

df.sub(df.mean())

Error: Failed to determine supertype of Int64 and Struct([Field { name: "A", dtype: Int32 }, Field { name: "B", dtype: Int32 }, Field { name: "C", dtype: Int32 }, Field { name: "D", dtype: Int32 }])

3。第二次尝试

df.sub(pl.Series(df.mean().row(0)))

Program crashes due to memory problems.

4。第三次尝试

经过一些调查,我注意到了 tests :

test("sub", () => {
const actual = pl.DataFrame({
"foo": [1, 2, 3],
"bar": [4, 5, 6]
}).sub(1);
const expected = pl.DataFrame({
"foo": [0, 1, 2],
"bar": [3, 4, 5]
});
expect(actual).toFrameEqual(expected);
});
test("sub:series", () => {
const actual = pl.DataFrame({
"foo": [1, 2, 3],
"bar": [4, 5, 6]
}).sub(pl.Series([1, 2, 3]));
const expected = pl.DataFrame({
"foo": [0, 0, 0],
"bar": [3, 3, 3]
});
expect(actual).toFrameEqual(expected);
});

nodejs-polars 现在似乎无法优雅地完成这个任务。所以我目前的解决方案有点麻烦:逐列执行操作然后连接结果。

pl.concat(df.columns.map((col) => df.select(col).sub(df.select(col).mean(0).toSeries())), {how:'horizontal'})

有更好或更简单的方法吗?

5。新的尝试

我刚刚提出了一个更简单的解决方案,但它很难理解,我仍在努力弄清楚幕后发生了什么。

df.select(pl.col('*').sub(pl.col('*').mean()))

最佳答案

你用 [python-polars] 标记了这个问题,所以我将提供一个使用 Polars 和 Python 的解决方案。 (也许您可以将其转换为 Node-JS。)

从我们的数据开始:

import polars as pl

df = pl.DataFrame(
{
"A": [13520, 13472, 13456, 13472, 13472],
"B": [-16, -16, -16, -16, -16],
"C": [384, 384, 368, 368, 352],
"D": [208, 176, 160, 160, 176],
}
)
df
shape: (5, 4)
┌───────┬─────┬─────┬─────┐
│ A ┆ B ┆ C ┆ D │
│ --- ┆ --- ┆ --- ┆ --- │
│ i64 ┆ i64 ┆ i64 ┆ i64 │
╞═══════╪═════╪═════╪═════╡
│ 13520 ┆ -16 ┆ 384 ┆ 208 │
├╌╌╌╌╌╌╌┼╌╌╌╌╌┼╌╌╌╌╌┼╌╌╌╌╌┤
│ 13472 ┆ -16 ┆ 384 ┆ 176 │
├╌╌╌╌╌╌╌┼╌╌╌╌╌┼╌╌╌╌╌┼╌╌╌╌╌┤
│ 13456 ┆ -16 ┆ 368 ┆ 160 │
├╌╌╌╌╌╌╌┼╌╌╌╌╌┼╌╌╌╌╌┼╌╌╌╌╌┤
│ 13472 ┆ -16 ┆ 368 ┆ 160 │
├╌╌╌╌╌╌╌┼╌╌╌╌╌┼╌╌╌╌╌┼╌╌╌╌╌┤
│ 13472 ┆ -16 ┆ 352 ┆ 176 │
└───────┴─────┴─────┴─────┘

我们可以非常简洁地解决这个问题:

df.with_columns([
(pl.all() - pl.all().mean()).suffix('_centered')
])
shape: (5, 8)
┌───────┬─────┬─────┬─────┬────────────┬────────────┬────────────┬────────────┐
│ A ┆ B ┆ C ┆ D ┆ A_centered ┆ B_centered ┆ C_centered ┆ D_centered │
│ --- ┆ --- ┆ --- ┆ --- ┆ --- ┆ --- ┆ --- ┆ --- │
│ i64 ┆ i64 ┆ i64 ┆ i64 ┆ f64 ┆ f64 ┆ f64 ┆ f64 │
╞═══════╪═════╪═════╪═════╪════════════╪════════════╪════════════╪════════════╡
│ 13520 ┆ -16 ┆ 384 ┆ 208 ┆ 41.6 ┆ 0.0 ┆ 12.8 ┆ 32.0 │
├╌╌╌╌╌╌╌┼╌╌╌╌╌┼╌╌╌╌╌┼╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌╌╌┤
│ 13472 ┆ -16 ┆ 384 ┆ 176 ┆ -6.4 ┆ 0.0 ┆ 12.8 ┆ 0.0 │
├╌╌╌╌╌╌╌┼╌╌╌╌╌┼╌╌╌╌╌┼╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌╌╌┤
│ 13456 ┆ -16 ┆ 368 ┆ 160 ┆ -22.4 ┆ 0.0 ┆ -3.2 ┆ -16.0 │
├╌╌╌╌╌╌╌┼╌╌╌╌╌┼╌╌╌╌╌┼╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌╌╌┤
│ 13472 ┆ -16 ┆ 368 ┆ 160 ┆ -6.4 ┆ 0.0 ┆ -3.2 ┆ -16.0 │
├╌╌╌╌╌╌╌┼╌╌╌╌╌┼╌╌╌╌╌┼╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌╌╌┤
│ 13472 ┆ -16 ┆ 352 ┆ 176 ┆ -6.4 ┆ 0.0 ┆ -19.2 ┆ 0.0 │
└───────┴─────┴─────┴─────┴────────────┴────────────┴────────────┴────────────┘

如果要覆盖列,可以去掉suffix表达式:

df.with_columns([
(pl.all() - pl.all().mean())
])
shape: (5, 4)
┌───────┬─────┬───────┬───────┐
│ A ┆ B ┆ C ┆ D │
│ --- ┆ --- ┆ --- ┆ --- │
│ f64 ┆ f64 ┆ f64 ┆ f64 │
╞═══════╪═════╪═══════╪═══════╡
│ 41.6 ┆ 0.0 ┆ 12.8 ┆ 32.0 │
├╌╌╌╌╌╌╌┼╌╌╌╌╌┼╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌┤
│ -6.4 ┆ 0.0 ┆ 12.8 ┆ 0.0 │
├╌╌╌╌╌╌╌┼╌╌╌╌╌┼╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌┤
│ -22.4 ┆ 0.0 ┆ -3.2 ┆ -16.0 │
├╌╌╌╌╌╌╌┼╌╌╌╌╌┼╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌┤
│ -6.4 ┆ 0.0 ┆ -3.2 ┆ -16.0 │
├╌╌╌╌╌╌╌┼╌╌╌╌╌┼╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌┤
│ -6.4 ┆ 0.0 ┆ -19.2 ┆ 0.0 │
└───────┴─────┴───────┴───────┘

编辑:本质上,polars.allpolars.col('*') 为每一列复制了一个完整的表达式,这样:

pl.col('*') - pl.col('*').mean()

是语法糖:

[
pl.col('A') - pl.col('A').mean(),
pl.col('B') - pl.col('B').mean(),
pl.col('C') - pl.col('C').mean(),
pl.col('D') - pl.col('D').mean(),
]

关于pandas - 如何在 polars DataFrame 中的每一列与该列的平均值之间轻松执行计算,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/72539701/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com