Как извлечь сегменты с одинаковым значением? - PullRequest
1 голос
/ 30 апреля 2019

У меня есть следующий фрейм данных,

df = pd.DataFrame({'col1':range(20), 'col2': list(range(3)) + [5] *3 +list(range(3)) + [3]*3 + list(range(4)) + [2]*3 + [4] }, 
        index = pd.date_range('1/1/2000', periods=20, freq='1S'))

df
Out[115]: 
                     col1  col2
2000-01-01 00:00:00     0     0
2000-01-01 00:00:01     1     1
2000-01-01 00:00:02     2     2
2000-01-01 00:00:03     3     5 *
2000-01-01 00:00:04     4     5 *
2000-01-01 00:00:05     5     5 *
2000-01-01 00:00:06     6     0
2000-01-01 00:00:07     7     1
2000-01-01 00:00:08     8     2
2000-01-01 00:00:09     9     3 *
2000-01-01 00:00:10    10     3 *
2000-01-01 00:00:11    11     3 *
2000-01-01 00:00:12    12     0
2000-01-01 00:00:13    13     1
2000-01-01 00:00:14    14     2
2000-01-01 00:00:15    15     3
2000-01-01 00:00:16    16     2 *
2000-01-01 00:00:17    17     2 *
2000-01-01 00:00:18    18     2 *
2000-01-01 00:00:19    19     4

Как видно выше, у меня в col2 три сегмента с одинаковыми значениями, и я хотел бы извлечь эти три сегмента:

                       col1  col2
2000-01-01 00:00:03     3     5
2000-01-01 00:00:04     4     5
2000-01-01 00:00:05     5     5


                       col1  col2
2000-01-01 00:00:09     9     3
2000-01-01 00:00:10    10     3
2000-01-01 00:00:11    11     3

                       col1  col2
2000-01-01 00:00:16    16     2
2000-01-01 00:00:17    17     2
2000-01-01 00:00:18    18     2

Как мне этого добиться?

Ответы [ 2 ]

2 голосов
/ 30 апреля 2019

Вот один способ, используя diff и cumsum для создания другой группы, затем мы используем transform и count, получаем количество групп и выбираем количество, равное 3, наконец, нам просто нужно groupby и разделить фрейм данных на col2

s=df.col2.diff().ne(0).cumsum()
l=[y for x , y  in df[s.groupby(s).transform('count')==3].groupby('col2')]
l[0]
Out[205]: 
                     col1  col2
2000-01-01 00:00:16    16     2
2000-01-01 00:00:17    17     2
2000-01-01 00:00:18    18     2
1 голос
/ 30 апреля 2019

Вот мой дубль:

df = pd.DataFrame({'col1':range(20), 'col2': list(range(3)) + [5] *3 +list(range(3)) + [3]*3 + list(range(4)) + [2]*3 + [4] }, 
        index = pd.date_range('1/1/2000', periods=20, freq='1S'))

# create markers for equal segment
df['markers'] = ((df.col2==df.col2.shift(-1)) & (df.col2 == df.col2.shift(-2))).cumsum()

# drop the first lines:
new_df = df[df['markers'] > 0].copy()

# output:
new_df.groupby('markers')[['col1','col2']].apply(lambda x: x[:3])

Выход:

+----------+----------------------+-------+------+
|          |                      | col1  | col2 |
+----------+----------------------+-------+------+
| markers  |                      |       |      |
+----------+----------------------+-------+------+
| 1        | 2000-01-01 00:00:03  |    3  |    5 |
|          | 2000-01-01 00:00:04  |    4  |    5 |
|          | 2000-01-01 00:00:05  |    5  |    5 |
| 2        | 2000-01-01 00:00:09  |    9  |    3 |
|          | 2000-01-01 00:00:10  |   10  |    3 |
|          | 2000-01-01 00:00:11  |   11  |    3 |
| 3        | 2000-01-01 00:00:16  |   16  |    2 |
|          | 2000-01-01 00:00:17  |   17  |    2 |
|          | 2000-01-01 00:00:18  |   18  |    2 |
+----------+----------------------+-------+------+
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...