python - 在 pandas df 中查找 A 列中的 True 值是否是他自 B 列中最后一个 True 以来的第一次出现

标签 python pandas dataframe vectorization

我正在寻找最有效的方法来查找 True column A 中的值是自上次以来第一次出现 True column B 中的值.

在此示例中,预期输出为 column C .

示例 1:

df = pd.DataFrame({
    'A': [False, False, True, False, True, False, True, False, True],
    'B': [True, False, False, False, False, True, False, False, False],
    'C': [False, False, True, False, False, False, True, False, False]
})
<表类="s-表"> <头> <日> A B C <正文> 0 错误 正确 错误 1 错误 错误 错误 2 正确 错误 正确 3 错误 错误 错误 4 正确 错误 错误 5 错误 正确 错误 6 正确 错误 正确 7 错误 错误 错误 8 正确 错误 错误

示例 2:

df = pd.DataFrame({
    'A': [True, False, False, True, False, True, False, True, False],
    'B': [False, True, False, False, False, False, True, False, False],
    'C': [False, False, False, True, False, False, False, True, False]
})
<表类="s-表"> <头> <日> A B C <正文> 0 正确 错误 错误 1 错误 正确 错误 2 错误 错误 错误 3 正确 错误 正确 4 错误 错误 错误 5 正确 错误 错误 6 错误 正确 错误 7 正确 错误 正确 8 错误 错误 错误

示例 3:

在这里你可以找到一个 .csv file with a bigger example

最佳答案

您可以对“B”列的累积总和使用 groupby 操作,按照您描述的方式对数据框进行分组。然后您可以使用 idxmax 获取列“A”中每个首次出现的索引。获得这些索引后,您可以创建新列“C”。

使用 idxmax 是一个小技巧,因为我们实际上对最大值不感兴趣,因为“A”列只有 TrueFalse 作为它的值。 idxmax 将返回最大值的第一次出现的索引(在这种情况下,True 在每个组中第一次出现),它是我们特别感兴趣的内容。

df = pd.DataFrame({
    'A': [False, False, True, False, True, False, True, False, True],
    'B': [True, False, False, False, False, True, False, False, False],
})

# get a dataframe of the position of the max as well as the max value
indices_df = df["A"].groupby(df["B"].cumsum()).agg(["idxmax", "max"])

# mask to filter out the 0th group
skip_0th = (indices_df.index > 0)

# mask to filter out groups who do not have True as a value
groups_with_true = (indices_df["max"] == True)

# combine masks and retrieve the appropriate index
indices = indices_df.loc[skip_0th & groups_with_true, "idxmax"]

df["C"] = False
df.loc[indices, "C"] = True

print(df)
       A      B      C
0  False   True  False
1  False  False  False
2   True  False   True
3  False  False  False
4   True  False  False
5  False   True  False
6   True  False   True
7  False  False  False
8   True  False  False

针对示例 2 进行了更新。

我们可以通过对索引系列进行切片以排除索引为 0 的任何条目来解决此问题(例如,标签从 1 切片到末尾)。这是有效的,因为我们的 groupby 操作根据 .cumsum 分配基于整数的标签。在示例 1 中,最小的索引标签将为 1(因为“B”列中的第一个值为 True)。而在示例 2 中,最小的索引标签将为 0。由于我们不希望 0 影响我们的结果,我们可以简单地将它从我们的 indices 中切掉。

当我们在对我们的 indices 系列执行切片后分配“C”时,我们将适本地忽略列“B”中第一次出现 True 之前的所有值。

不过文字已经够多了,让我们看一些代码。

示例 1

print(indices)
1    2
2    6

# Slicing here doesn't change anything, since indices does not have
#  a value corresponding to label position 0
indices = indices.loc[1:]
print(indices)
1    2
2    6

示例 2

print(indices)
0    0
1    3
2    7

# we don't want to include the value from label position 0 in `indices`
#  so we can use slicing to remove it

indices = indices.loc[1:]
print(indices)
1    3
2    7  

关于python - 在 pandas df 中查找 A 列中的 True 值是否是他自 B 列中最后一个 True 以来的第一次出现,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/70174822/

相关文章:

python - 物体只占图像一小部分的物体检测

r - 将数据框中的因子转换为整数

r - 对 data.frame 或矩阵中的行求和

python - 如何处理空 'DataFrame' : no numeric data to plot error to take string on the graphs

python - 为 Flask 应用程序创建系统服务时如何解决 (code=exited,status=203/Exec)

python - 如何在 Python 多处理池中运行清理代码?

python - 导入错误 : cannot import name 'DtypeArg' from 'pandas

python-2.7 - Pandas :一种使用namedtuple列表初始化数据帧的干净方法

python - 使用 Gekko 的约束多重线性回归

装饰器的 Python 3 类型提示