Групповые значения в пандах

У меня есть следующие данные в файле csv. Я хочу сгруппировать значения в столбце «Значение», чтобы он разбивался и печатал количество Истинный и ЛОЖЬ, если получил как минимум два последовательных значения. Я хочу добиться этого с помощью панд, потому что у меня будут огромные данные, и мне нужно будет вычислить их за меньшее время.

ДатаЦенность
2022-05-16 17:54:30Истинный
2022-05-16 17:54:50Истинный
2022-05-16 17:55:01Истинный
2022-05-16 17:57:34ЛОЖЬ
2022-05-16 17:57:44Истинный
2022-05-16 17:57:44Истинный
2022-05-16 17:57:54ЛОЖЬ
2022-05-16 17:58:35ЛОЖЬ
2022-05-16 18:31:43ЛОЖЬ
2022-05-16 18:31:43ЛОЖЬ
2022-05-16 18:31:43Истинный
2022-05-16 18:31:54Истинный
2022-05-16 18:31:54Истинный
2022-05-16 18:31:54ЛОЖЬ
2022-05-16 18:32:45ЛОЖЬ
2022-05-16 18:32:45ЛОЖЬ
2022-05-16 18:32:45ЛОЖЬ
2022-05-16 18:33:15Истинный
2022-05-16 18:33:15ЛОЖЬ
2022-05-16 18:33:25ЛОЖЬ
2022-05-16 18:33:25ЛОЖЬ

Вывод должен быть таким

True: 5
False: 1
2022-05-16 17:57:44

True: 0
False: 4
2022-05-16 18:31:43

True: 3
False: 0
2022-05-16 18:31:54

True: 1
False: 7
2022-05-16 18:33:25

Что вы считаете «по крайней мере двумя последовательными значениями»?

jjsantoso 16.05.2022 22:59

@jjsantoso одинаковые значения появляются в двух последовательных записях

Khizar Shujaat 16.05.2022 23:02

В приведенном вами примере данных есть только две строки с датой =="2022-05-16 17:57:44", но вывод предполагает, что есть 6 строк

jjsantoso 16.05.2022 23:06

Вывод отображает дату последней записи, когда следующие два последовательных «Значения» встречаются как true, true или false, false

Khizar Shujaat 16.05.2022 23:12
Анализ настроения постов в Twitter с помощью Python, Tweepy и Flair
Анализ настроения постов в Twitter с помощью Python, Tweepy и Flair
Анализ настроения текстовых сообщений может быть настолько сложным или простым, насколько вы его сделаете. Как и в любом ML-проекте, вы можете выбрать...
7 лайфхаков для начинающих Python-программистов
7 лайфхаков для начинающих Python-программистов
В этой статье мы расскажем о хитростях и советах по Python, которые должны быть известны разработчику Python.
Установка Apache Cassandra на Mac OS
Установка Apache Cassandra на Mac OS
Это краткое руководство по установке Apache Cassandra.
Сертификатная программа "Кванты Python": Бэктестер ансамблевых методов на основе ООП
Сертификатная программа "Кванты Python": Бэктестер ансамблевых методов на основе ООП
В одном из недавних постов я рассказал о том, как я использую навыки количественных исследований, которые я совершенствую в рамках программы TPQ...
Создание персонального файлового хранилища
Создание персонального файлового хранилища
Вы когда-нибудь хотели поделиться с кем-то файлом, но он содержал конфиденциальную информацию? Многие думают, что электронная почта безопасна, но это...
Создание приборной панели для анализа данных на GCP - часть I
Создание приборной панели для анализа данных на GCP - часть I
Недавно я столкнулся с интересной бизнес-задачей - визуализацией сбоев в цепочке поставок лекарств, которую могут просматривать врачи и...
2
4
31
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Для этого вам нужно создать переменную, которая указывает, когда начинается и заканчивается новая «фаза». Новая фаза — это когда происходит разрыв, то есть когда за строкой следуют два последовательных значения, которые отличаются от фактической строки. Чтобы получить это phase, я сначала создал столбец «sum_next_two», который для каждой строки вычисляет сумму следующих двух строк. Нас интересуют строки, где sum_next_two==2 или sum_next_two==0, потому что они указывают на начало/конец новой фазы. Итак, когда phase==True это положительная фаза, которая заканчивается, когда sum_next_two==0. Затем начните отрицательную фазу (phase==False), которая заканчивается, когда sum_next_two==0. После определения всех существующих фаз создайте переменную group, которая создаст уникальный номер для каждой фазы.

import pandas as pd

data = [{'Date': '2022-05-16 17:54:30', 'Value': True},
 {'Date': '2022-05-16 17:54:50', 'Value': True},
 {'Date': '2022-05-16 17:55:01', 'Value': True},
 {'Date': '2022-05-16 17:57:34', 'Value': False},
 {'Date': '2022-05-16 17:57:44', 'Value': True},
 {'Date': '2022-05-16 17:57:44', 'Value': True},
 {'Date': '2022-05-16 17:57:54', 'Value': False},
 {'Date': '2022-05-16 17:58:35', 'Value': False},
 {'Date': '2022-05-16 18:31:43', 'Value': False},
 {'Date': '2022-05-16 18:31:43', 'Value': False},
 {'Date': '2022-05-16 18:31:43', 'Value': True},
 {'Date': '2022-05-16 18:31:54', 'Value': True},
 {'Date': '2022-05-16 18:31:54', 'Value': True},
 {'Date': '2022-05-16 18:31:54', 'Value': False},
 {'Date': '2022-05-16 18:32:45', 'Value': False},
 {'Date': '2022-05-16 18:32:45', 'Value': False},
 {'Date': '2022-05-16 18:32:45', 'Value': False},
 {'Date': '2022-05-16 18:33:15', 'Value': True},
 {'Date': '2022-05-16 18:33:15', 'Value': False},
 {'Date': '2022-05-16 18:33:25', 'Value': False},
 {'Date': '2022-05-16 18:33:25', 'Value': False}]

df = pd.DataFrame(data)

# for each row, calculates the sum of the next two rows
df['sum_next_two'] = df['Value'].rolling(2).sum().shift(-2).fillna(method='ffill')

# We are interested in rows where sum_next_two==2 or sum_next_two==0, because they indicate the start/end of a new phase
df.loc[0, 'phase'] = True
df.loc[df['sum_next_two'].eq(2), 'phase'] = True
df.loc[df['sum_next_two'].eq(0), 'phase'] = False
df['phase'] = df['phase'].shift(1).fillna(method='ffill')
# identify uniquely each phase
df['group'] = df['phase'].diff().abs().cumsum().fillna(method='bfill')
df

enter image description here

После этого просто агрегируйте, чтобы получить желаемый результат:

df.groupby('group').agg(total_true=('Value', 'sum'), total_rows=('Value', 'count'), date=('Date', 'max'))\
    .assign(total_false=lambda x: x['total_rows'] - x['total_true'])\
    [['date', 'total_true', 'total_false']]

enter image description here

Другие вопросы по теме