分组依据搜索第一个和最后一个 True 值



我有一个pd。具有重复索引的系列,每个索引包含一组布尔值:

FA155    False
FA155    False
FA155    False
FA155    True
FA155    True
FA155    True
FA155    True
FA155    True
FA155    False

我试图以一种有效的方式为每个不同的索引做的是仅将序列的第一个和最后一个 True 值保留为 True,并将其余值设置为 False。在 True 值之间也可以存在 False 值。

因此,对于此示例,结果将是:

FA155    False
FA155    False
FA155    False
FA155    True
FA155    False
FA155    False
FA155    False
FA155    True
FA155    False

任何帮助将不胜感激。

您可以将loc与原始df和反转df一起使用idxmax

这将生成第一个和最后一个True值的索引。只需将不同的索引设置为之后False即可。

例如:

设置

z = sio("""i    v
FA154    False
FA155    False
FA155    True
FA155    True
FA155    True
FA155    True
FA155    True
FA155    False
FA156    False
FA156    True
FA156    False
FA156    False
FA156    True""")
df = pd.read_table(z, delim_whitespace=True)
i       v
0   FA154   False
1   FA155   False
2   FA155   True
3   FA155   True
4   FA155   True
5   FA155   True
6   FA155   True
7   FA155   False
8   FA156   False
9   FA156   True
10  FA156   False
11  FA156   False
12  FA156   True

idxmax()

这与获取df和使用reset_index相同。然后,获取索引列表的第一个(v1(和最后一个(v2(True值:

v1 = df.groupby("i").v.idxmax().values
v2 = df[::-1].groupby("i").v.idxmax().values

并使用您的逻辑:

df.loc[v1, "v"] = True & df.loc[v1, "v"]
df.loc[v2, "v"] = True & df.loc[v2, "v"]
df.loc[~df.index.isin(np.concatenate([v1,v2])), "v"] = False

使用&背后的想法是不要意外地将任何False值设置为True.

结果:

>>> df.set_index("i")
v
i   
FA154   False
FA155   False
FA155   True
FA155   False
FA155   False
FA155   False
FA155   True
FA155   False
FA156   False
FA156   True
FA156   False
FA156   False
FA156   True

筛选True 值,然后聚合以查找第一个和最后一个值。然后,您可以使用 loc 替换 df 中的这些值。df是您的数据帧。col是具有True值和False值的列的名称

df["nb"] = range(df.shape[0])
df.reset_index(inplace=True)
elem = (df[df[col]==True].groupby("index")["nb"].agg({ "first_True": 'first', "last_True":"last"})).values
indexes_to_False = sum(elem.tolist(), [])
df.loc[indexes_to_False, col] = False

然后,您可以根据需要删除nb列并重新索引

这是基于获取组起点diff,我使用iloc两次,因为您需要保持头部和尾部 True

df1=df.copy()
df.loc[df]=df.astype(int).diff().ne(0)[df]
df=df.iloc[::-1]
df1=df1.iloc[::-1]
df.loc[df1]+=df1.astype(int).diff().ne(0)[df1]
df=df.iloc[::-1]

相关内容

最新更新