我有一个带有重复索引的pd.Series,每个索引都包含一组布尔值:
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
非常感谢任何帮助。
答案 0 :(得分:3)
您可以将loc
与idxmax
一起使用原始df
和倒置df
。
这将产生您的第一个和最后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
答案 1 :(得分:1)
You filter True values and then you aggregate to find the first and last values. Then you can use loc to replace those values in df.
df
is your dataframe. col
is the name of your column with True
and False
values
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
Then you can drop the column nb
and reindex if you wish
答案 2 :(得分:1)
This is based on the diff
to get the group starting point , I am using iloc
twice since you need keep the head and tail 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]