Групповой поиск первых и последних истинных значений - PullRequest
0 голосов
/ 28 мая 2018

У меня есть pd.Series с дублированными индексами, и каждый индекс содержит набор логических значений:

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

Что я пытаюсь сделать для каждого отдельного индекса эффективным способом, это сохранитьтолько как True - первое и последнее значения True последовательности, а для остальных - False.Между значениями True также могут быть ложные значения.

Так что для этого примера результат будет:

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

Любая помощь будет очень признательна.

Ответы [ 3 ]

0 голосов
/ 28 мая 2018

Вы фильтруете Истинные значения, а затем агрегируете, чтобы найти первое и последнее значения.Затем вы можете использовать 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 и переиндексировать, если хотите

0 голосов
/ 28 мая 2018

Это основано на 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]
0 голосов
/ 28 мая 2018

Вы можете использовать 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
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...