Рассмотрим следующий фрейм данных, где 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)
🤔 А знаете ли вы, что...
С Python можно создавать роботов и автоматизированные системы с использованием библиотеки Raspberry Pi.
# 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.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
'''