【问题标题】:Pandas efficiently applying a function that depends on index valuePandas 有效地应用依赖于索引值的函数
【发布时间】:2021-11-04 14:52:45
【问题描述】:

我有一个带有多索引 d, y, b, r, a 的 pandas 数据框,我需要应用一个函数,根据索引值在数据框的元素之间进行减法。

为了简化,我将只考虑三个索引,d, y, r

索引 d 可以取两个值 value0value1。当d == value0 时,索引r 只能是"O"。相反,当d == value1 r 是 0 到 999 之间的整数时。其余索引在 value0value1 之间是通用的。

数据框可以构造为

import numpy as np
import pandas as pd
d_index = [*["value0", "value0"], *["value1" for _ in range(2000)]]

y_index = [*[0, 1], *[0 for _ in range(1000)], *[1 for _ in range(1000)]]

r_index = [*["O", "O"], *[i for i in range(1000)], *[i for i in range(1000)]]

rng = np.random.default_rng(12345)

results00 = rng.uniform(0, 2, 1000).tolist()
results01 = rng.uniform(0, 2, 1000).tolist()

results20 = rng.uniform(0, 6, 1000).tolist()
results21 = rng.uniform(0, 6, 1000).tolist()


variable0 = [1, 2, *results00, *results01]

variable2 = [
    2.5,
    3.5,
    *results20,
    *results21,
]

df = pd.DataFrame(
    {
        "d": d_index,
        "y": y_index,
        "r": r_index,
        "string0": variable0,
        "string2": variable2,
    }
)

df.set_index(["d", "y", "r"], inplace=True)

我需要计算某些列之间的差异,以便除value0value1 之外的所有索引都相同。结果可以通过:

df.loc[("value1", 0), "dstring0"] = (df.loc[("value0", 0), "string0"]).to_numpy() - (
    df.loc[("value1", 0), "string0"]
).to_numpy()

df.loc[("value1", 1), "dstring0"] = (df.loc[("value0", 1), "string0"]).to_numpy() - (
    df.loc[("value1", 1), "string0"]
).to_numpy()

df.loc[("value1", 0), "dstring2"] = (df.loc[("value0", 0), "string2"]).to_numpy() - (
    df.loc[("value1", 0), "string2"]
).to_numpy()

df.loc[("value1", 1), "dstring2"] = (df.loc[("value0", 1), "string2"]).to_numpy() - (
    df.loc[("value1", 1), "string2"]
).to_numpy()

我可以通过循环 y, b, a 索引并执行上述减法来处理这种转换,但是考虑到大量观察(大约 800 万),它不会有效

我怎样才能有效地处理操作?

编辑:添加了示例数据框和预期输出。我也意识到以前的功能不起作用。我把它放在下面作为参考

错误的功能

def deviation(df_slice, df, variables):
    d, y, b, r, a = df_slice.name
    dvars = ["d" + var for var in variables]
    if d == "value1":
        df.loc[(d, y, b, r, a), dvars] = (
            df.loc[("value0", y, b, "O", a), variables].to_numpy()
            - df_slice[variables].to_numpy()
        )

df.apply(deviation, axis=1, variables=['string0','string2'],df=df)

【问题讨论】:

  • 请提供一个示例数据集(作为数据框构造函数,因为这是一个 MultiIndex)和预期输出
  • 我已经根据您的要求更新了帖子。而且我意识到我的功能不起作用。

标签: python pandas dataframe performance


【解决方案1】:

简单的答案更快。但是,它只会让你的表现提高一点点(2 倍):

import swifter

df.swifter.apply(deviation, axis=1, variables=['string0','string2'],df=df)

查看来自面向datascience.com 的this article,了解更好的熊猫矢量化概念。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2022-10-16
    • 2020-05-11
    • 1970-01-01
    • 2015-07-02
    • 1970-01-01
    • 1970-01-01
    • 2012-07-28
    相关资源
    最近更新 更多