Группируйте элементы в фрейме данных и отображайте их в хронологическом порядке

Рассмотрим следующий фрейм данных, где Date имеет формат DD-MM-YYY:

Date        Time      Table
01-10-2000  13:00:03  B
01-10-2000  13:00:04  A
01-10-2000  13:00:05  B
01-10-2000  13:00:06  A
01-10-2000  13:00:07  B
01-10-2000  13:00:08  A

Как я могу 1) сгруппировать наблюдения по Table, 2) отсортировать строки по Date и Time внутри каждой группы, 3) показать группы в хронологическом порядке согласно Date и Time их первого наблюдения?

Date        Time      Table
01-10-2000  13:00:03  B
01-10-2000  13:00:05  B
01-10-2000  13:00:07  B
01-10-2000  13:00:04  A
01-10-2000  13:00:06  A
01-10-2000  13:00:08  A

Входные данные:

data = {
    'Date': ['01-10-2000', '01-10-2000', '01-10-2000', '01-10-2000', '01-10-2000', '01-10-2000'],
    'Time': ['13:00:03', '13:00:04', '13:00:05', '13:00:06', '13:00:07', '13:00:08'],
    'Table': ['B', 'A', 'B', 'A', 'B', 'A']
}
df = pd.DataFrame(data)

Здесь есть несколько движущихся частей, и это граничит с «несколько вопросов в одном». Для начала, знаете ли вы как конвертировать строки в дату и время? Сделайте это сначала, чтобы вопрос был проще. Во-первых, формат даты совершенно не имеет отношения к проблеме.

wjandrea 04.09.2024 23:59
Почему в Python есть оператор "pass"?
Почему в Python есть оператор "pass"?
Оператор pass в Python - это простая концепция, которую могут быстро освоить даже новички без опыта программирования.
Некоторые методы, о которых вы не знали, что они существуют в Python
Некоторые методы, о которых вы не знали, что они существуют в Python
Python - самый известный и самый простой в изучении язык в наши дни. Имея широкий спектр применения в области машинного обучения, Data Science,...
Основы Python Часть I
Основы Python Часть I
Вы когда-нибудь задумывались, почему в программах на Python вы видите приведенный ниже код?
LeetCode - 1579. Удаление максимального числа ребер для сохранения полной проходимости графа
LeetCode - 1579. Удаление максимального числа ребер для сохранения полной проходимости графа
Алиса и Боб имеют неориентированный граф из n узлов и трех типов ребер:
Оптимизация кода с помощью тернарного оператора Python
Оптимизация кода с помощью тернарного оператора Python
И последнее, что мы хотели бы показать вам, прежде чем двигаться дальше, это
Советы по эффективной веб-разработке с помощью Python
Советы по эффективной веб-разработке с помощью Python
Как веб-разработчик, Python может стать мощным инструментом для создания эффективных и масштабируемых веб-приложений.
2
1
50
3
Перейти к ответу Данный вопрос помечен как решенный

Ответы 3

# Sort by Date and Time
df['DateTime'] = pd.to_datetime(df['Date'] + ' ' + df['Time'], format='%d-%m-%Y %H:%M:%S')
df_sorted = df.sort_values('DateTime')

# Find the first occurrence of each Table group
first_occurrences = df_sorted.groupby('Table', as_index=False).first()

# Sort Table groups according to the Date and Time of their first occurrence
table_order = first_occurrences.sort_values('DateTime')['Table']

# Create categorical version of 'Table' specifying the order of the categories
df_sorted['Table_cat'] = pd.Categorical(df_sorted['Table'], categories=table_order, ordered=True)

# Sort the dataframe
result = df_sorted.sort_values(['Table_cat', 'DateTime'])
result = result.reset_index(drop=True).drop('Table_cat', axis=1)

Вместо groupby, pd.Categorical и т. д. вы можете просто создать столбец DateTime, а затем использовать result = df.sort_values(['Table', 'DateTime'], ascending = [False, True]).drop('DateTime', axis=1), который дает ожидаемый результат.

user19077881 05.09.2024 00:25
Ответ принят как подходящий

Используйте groupby.transform и numpy.lexsort:

date = pd.to_datetime(df['Date']+' '+df['Time'])

out = df.iloc[np.lexsort([
    date,
    df['Table'],
    date.groupby(df['Table']).transform('min')
])]

Альтернативно, используя промежуточный столбец:

date = pd.to_datetime(df['Date']+' '+df['Time'])

out = (df.assign(date=date, min_date=date.groupby(df['Table']).transform('min'))
         .sort_values(by=['min_date', 'Table', 'date'])
         .drop(columns=['date', 'min_date'])
     )

Выход:

         Date      Time Table
0  01-10-2000  13:00:03     B
2  01-10-2000  13:00:05     B
4  01-10-2000  13:00:07     B
1  01-10-2000  13:00:04     A
3  01-10-2000  13:00:06     A
5  01-10-2000  13:00:08     A
import pandas as pd
import numpy as np

data = {
    'Date': ['01-10-2000', '01-10-2000', '01-10-2000', '01-10-2000', '01-10-2000', '01-10-2000'],
    'Time': ['13:00:03', '13:00:04', '13:00:05', '13:00:06', '13:00:07', '13:00:08'],
    'Table': ['B', 'A', 'B', 'A', 'B', 'A']
}
df = pd.DataFrame(data)
'''
         Date      Time Table
0  01-10-2000  13:00:03     B
1  01-10-2000  13:00:04     A
2  01-10-2000  13:00:05     B
3  01-10-2000  13:00:06     A
4  01-10-2000  13:00:07     B
5  01-10-2000  13:00:08     A
'''

res = df.iloc[np.lexsort(df['Table'].values + 
        pd.to_datetime(df['Date'] + ' ' + df['Time']).astype(str))
        ].reset_index(drop=True)

print(res)
'''
         Date      Time Table
0  01-10-2000  13:00:04     A
1  01-10-2000  13:00:06     A
2  01-10-2000  13:00:08     A
3  01-10-2000  13:00:03     B
4  01-10-2000  13:00:05     B
5  01-10-2000  13:00:07     B
'''

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

Похожие вопросы

Операции Pandas между типами с плавающей запятой и NaN
Используйте спецификатор формата для преобразования столбца float/int в фрейме данных Polars в строку
Как ВСТАВИТЬ в таблицу с помощью AUTO_INCREMENT?
Дилемма 100 заключенных: кодекс всегда приводит к провалу (все заключенные умирают)
Как устранить ошибку AttributeError: у модуля «Фиона» нет атрибута «Путь»?
Я работаю над тем, чтобы сделать бота Python, который будет нажимать кнопку в списке, который повторяется сам, используя селен
Какие замены регулярных выражений помогают при переписывании SQL-запросов MS Access как простых запросов TSQL? Как их можно зациклить с помощью Excel в качестве входных и выходных данных?
Сообщение об ошибке с использованием нескольких замен строк %s
Должны ли классы аутентификации и классы разрешений в представлениях Django REST Framework определяться с помощью списков или кортежей?
Есть ли сценарий, в котором `foo in list(bar)` нельзя заменить на `foo in bar`?