Pandas подмножество на основе групп - PullRequest
0 голосов
/ 25 марта 2020

У меня ниже pandas датафрейм.

   a   b
0  5  10
1  6  12
2  9   4
3  8   3
4  3   6
5  2   7
6  4   5

Теперь я могу sh получить последнее подмножество, которое не соответствует условию df.a> df.b. Означает, что если мы создадим новый столбец, чтобы лучше это понять, он будет выглядеть следующим образом.

   a   b     c
0  5  10  Down
1  6  12  Down
2  9   4    Up
3  8   3    Up
4  3   6  Down
5  2   7  Down
6  4   5  Down

Исходя из вышесказанного, я получу sh, чтобы получить последнее подмножество df. c, имеющее то же значение «Вниз», что означает, что выходные данные будут иметь последние три строки, как показано ниже.

   a   b     c
4  3   6  Down
5  2   7  Down
6  4   5  Down

Я написал код ниже. Но я ничего не понимаю после этого.

import pandas as pd
import numpy as np


df = pd.DataFrame([[5, 10], [6, 12], [9, 4], [8, 3], [3, 6], [2, 7], [4, 5]], columns=["a", "b"])
df['c'] = np.where(df.a > df.b,'Up','Down')
print(df)

Пожалуйста, помогите мне в этом.

Ответы [ 3 ]

2 голосов
/ 25 марта 2020

Решением для получения последней группы заполненных Down значений является сначала получение групп для каждого последовательного значения s, созданного Series.ne, Series.shift и Series.cumsum, затем отфильтруйте его по Down значениям с маской, созданной с помощью Series.eq, получите максимальное значение для последней группы и исходный последний фильтр s значение для конечной маски - последний фильтр boolean indexing:

s = df['c'].ne(df['c'].shift()).cumsum()
m = df['c'].eq('Down')
df = df[s.eq(s[m].max())]
print (df)
   a  b     c
4  3  6  Down
5  2  7  Down
6  4  5  Down

Подробности :

print (s)
0    1
1    1
2    2
3    2
4    3
5    3
6    3
Name: c, dtype: int32

print (m)
0     True
1     True
2    False
3    False
4     True
5     True
6     True
Name: c, dtype: bool

print (s[m])
0    1
1    1
4    3
5    3
6    3
Name: c, dtype: int32

print (s[m].max())
3

print (s.eq(s[m].max()))
0    False
1    False
2    False
3    False
4     True
5     True
6     True
Name: c, dtype: bool
1 голос
/ 25 марта 2020

Вот один с more_itertools.consecutive_groups:

from more_itertools import consecutive_groups
m = df[df['c'].eq('Down')]
df.loc[[list(i) for i in consecutive_groups(m.index)][-1]] #-1 takes the last group

   a  b     c
4  3  6  Down
5  2  7  Down
6  4  5  Down

Где:

[list(i) for i in consecutive_groups(m.index)]

Выходы:

[[0, 1], [4, 5, 6]]
0 голосов
/ 25 марта 2020

Вот одно из решений,

df = df.iloc[((df['c'].shift() == "Up") & (df['c'] == "Down")).idxmax():, :]
print(df)

   a  b     c
4  3  6  Down
5  2  7  Down
6  4  5  Down
...