【问题标题】:How to vectorize pandas code where it depends on previous row?如何对依赖于前一行的熊猫代码进行矢量化?
【发布时间】:2021-06-11 12:08:16
【问题描述】:

我正在尝试对 pandas 中的代码 sn-p 进行矢量化:

我有一个这样生成的熊猫数据框:

ids ftest vals
0 Q52EG 0 0
1 Q52EG 0 1
2 Q52EG 1 2
3 Q52EG 1 3
4 Q52EG 1 4
5 QQ8Q4 0 5
6 QQ8Q4 0 6
7 QQ8Q4 1 7
8 QQ8Q4 1 8
9 QVIPW 1 9

如果ids 列中的任何id 在ftest 列中的值为1,则在has_hist 列中所有具有相同id 的后续行都应标记为1,并且它不依赖于当前ftest值如下图所示:

ids ftest vals has_hist
0 Q52EG 0 0 0
1 Q52EG 0 1 0
2 Q52EG 1 2 0
3 Q52EG 1 3 1
4 Q52EG 1 4 1
5 QQ8Q4 0 5 0
6 QQ8Q4 0 6 0
7 QQ8Q4 1 7 0
8 QQ8Q4 1 8 1
9 QVIPW 1 9 0

我正在使用这样的迭代方法:

previous_present = {}
has_prv_history = []
for index, value in id_df.iterrows():
    my_id = value["ids"]
    ftest_mentioned = value["ftest"]
    previous_flag = 0
    if my_id in previous_present.keys():
        previous_flag = 1
    elif (ftest_mentioned == 1):
        previous_present[my_id] = 1
    has_prv_history.append(previous_flag)
id_df["has_hist"] = has_prv_history

可以不使用apply 对这段代码进行矢量化吗?

【问题讨论】:

    标签: python pandas numpy-ndarray


    【解决方案1】:

    此类任务的两个关键函数是shiftffill,按组应用。对于这个特定的问题:

    df2["has_hist"] = df.groupby("ids").ftest.shift().where(lambda s: s.eq(1))
    df2["has_hist"] = df2.groupby("ids").has_hist.ffill().fillna(0).astype("int32")
    

    这是transform 的变体,但根据我的经验,它通常比“纯”Pandas 操作慢:

    df2 = (
        df
        .groupby("ids")
        .ftest.transform(
            lambda s: (
                s
                .shift()
                .where(lambda t: t.eq(1))
                .ffill()
                .fillna(0)
                .astype("int32")
            )
        )
    )
    

    【讨论】:

      猜你喜欢
      • 2022-09-27
      • 2021-11-26
      • 2020-12-25
      • 2021-02-16
      • 1970-01-01
      • 1970-01-01
      • 2020-11-11
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多