迭代地向前填充pandas列,但不使用迭代?

roqulrg3  于 2023-11-15  发布在  其他
关注(0)|答案(2)|浏览(90)

我有一个pandas数据框,其中一列满足基于数据框中其他元素的条件(未显示)。此外,我有一列,它使用以下规则将有效性进一步扩展一行:

如果有效行后面直接跟有ExtendsValid,则该行也有效,即使底层有效条件不适用。只要ExtendsValid为1,就继续向前填充有效行

我已经在列“FinalValid”中说明了结果(所需的结果。不必是新列,也可以向前填充Valid)。请注意,示例中的第8行和第9行也变得有效。还要注意,第13行不会导致FinalValid,因为您需要前面的有效行。前面的有效行可以是Valid或扩展的有效行。
到目前为止,如果我遇到这样的问题,我会做一个繁琐的多步骤过程:
1.当“Valid”或“ExtendsValid”为true时创建一个新列
1.创建一个新列,标记每个“子系列”(一组连续的子系列)的起点
1.为每个子系列编号

  1. fillna对每个子系列使用“group by”
    我可以提供示例代码,但我真的在寻找一种完全不同的,更有效的方法,当然也必须是非迭代的。
    任何想法都将受到欢迎。
    | 数量|有效|扩展有效|最终有效|
    | --|--|--|--|
    | 1 | 0 | 0 | 0 |
    | 2 | 1 | 0 | 1 |
    | 3 | 0 | 0 | 0 |
    | 4 | 0 | 0 | 0 |
    | 5 | 1 | 0 | 1 |
    | 6 | 0 | 0 | 0 |
    | 7 | 1 | 0 | 1 |
    | 8 | 0 | 1 | 1 |
    | 9 | 0 | 1 | 1 |
    | 10 | 0 | 0 | 0 |
    | 11 | 1 | 0 | 1 |
    | 12 | 0 | 0 | 0 |
    | 13 | 0 | 1 | 0 |
    | 14 | 0 | 0 | 0 |
jvidinwx

jvidinwx1#

IIUC,只有当从Valid开始并最终在ExtendsValid上继续存在一系列不间断的1时,才需要填充1。
为此,您可以使用groupby.cummin

df['FinalValid'] = (
 (df['Valid']|df['ExtendsValid'])
 .groupby(df['Valid'].cumsum())
 .cummin()
 )

字符串
输出量:

  • 注:我稍微修改了第3行的输入,以更好地说明逻辑。*
#  Valid  ExtendsValid  FinalValid
0    1      0             0           0
1    2      1             0           1
2    3      0             0           0
3    4      0             1           0
4    5      1             0           1
5    6      0             0           0
6    7      1             0           1
7    8      0             1           1
8    9      0             1           1
9   10      0             0           0
10  11      1             0           1
11  12      0             0           0

bq3bfh9z

bq3bfh9z2#

试试看:

state, data = 0, []
for v, e in zip(df.Valid, df.ExtendsValid):
    state = v or (not v and e and state)
    data.append(int(state))

df["FinalValid_new"] = data
print(df)

字符串
打印:

#  Valid  ExtendsValid  FinalValid  FinalValid_new
0    1      0             0           0               0
1    2      1             0           1               1
2    3      0             0           0               0
3    4      0             0           0               0
4    5      1             0           1               1
5    6      0             0           0               0
6    7      1             0           1               1
7    8      0             1           1               1
8    9      0             1           1               1
9   10      0             0           0               0
10  11      1             0           1               1
11  12      0             0           0               0
12  13      0             1           0               0
13  14      0             0           0               0


注意:要获得更高的性能,我建议查看numba包。
编辑:使用numba的示例:

from numba import njit

@njit
def compute_valid(valid, extends_valid, out):
    state = 0
    for i, (v, e) in enumerate(zip(valid, extends_valid)):
        state = v or (not v and e and state)
        out[i] = int(state)

df["FinalValid_new"] = 0
compute_valid(
    df.Valid.to_numpy(), df.ExtendsValid.to_numpy(), df.FinalValid_new.to_numpy()
)
print(df)

相关问题