#python #pandas #group-by #aggregation
#python #pandas #группировать по #агрегация
Вопрос:
Я пытаюсь что-то сделать, и мне интересно, можно ли это сделать в Pandas или есть инструмент получше для этой работы (в настоящее время я просто использую для этого обычный python). Вот исходные данные:
# We have a listing of files for the movie Titanic
# And we want to break them into groups of similar titles,
# To see which of those are possible duplicates.
import pandas as pd
titanic_files = [
{"File": "Titanic_HD2398.mov", "Resolution": "HD", "FrameRate": 23.98, "Runtime": 102},
{"File": "Titanic1.mov", "Resolution": "SD", "FrameRate": 23.98, "Runtime": 102},
{"File": "Titanic1.mov", "Resolution": "HD", "FrameRate": 23.98, "Runtime": 102},
{"File": "Titanic.mov", "Resolution": "HD", "FrameRate": 24.00, "Runtime": 103},
{"File": "MY_HD2398.mov", "Resolution": "HD", "FrameRate": 23.98, "Runtime": 102}
]
df = pd.DataFrame(titanic_files)
И я хочу сгруппировать эти файлы по похожим данным, никогда не сворачивая данные на уровне строк, например:
-
Шаг 1 — Группировка по разрешению
---- HD ---- File Resolution FrameRate RunTime Titanic_HD2398.mov HD 23.98 102 Titanic1.mov HD 23.98 102 Titanic.mov HD 24.00 103 MY_HD2398.mov HD 23.98 102 ---- SD ---- File Resolution FrameRate RunTime Titanic1.mov SD 23.98 102
-
Шаг 2 — Группировка по частоте кадров
---- HD ----------------------- ----------- 23.98 ------------ File Resolution FrameRate RunTime Titanic_HD2398.mov HD 23.98 102 Titanic1.mov HD 23.98 102 MY_HD2398.mov HD 23.98 102 ----------- 24.00 ------------ File Resolution FrameRate RunTime Titanic.mov HD 24.00 103 ---- SD ----------------------- ---------- 23.98 ------------ File Resolution FrameRate RunTime Titanic1.mov SD 23.98 102
И, в конце концов, я хочу в основном иметь отдельные фреймы данных для каждой из наименьших групп. В python я в настоящее время делаю это со следующей структурой данных:
{
'GroupingKeys': [{File1WithinThatBucket}, {File2WithinThatBucket}, ...]
}
Например:
{
'HD 23.98' [{'File': ...}],
'HD 24.00' [{'File': ...}]
}
Также, пожалуйста, имейте в виду, что существует около 10-15 полей, по которым я группирую, я только что включил два в приведенный выше вопрос, поэтому этот подход должен быть довольно обобщенным (кроме того, некоторые критерии соответствия не точны, например, время выполнения может быть привязано к чему-то вроде / — 2 секунд, некоторые значения могут быть нулевыми и т.д.).
И вернемся к первоначальному вопросу: можно ли что-то подобное сделать в Pandas, и если да, то как?
Ответ №1:
Pandas groupby
кажется используемым инструментом, он может использовать столько группировок, сколько необходимо, и они могут быть типа list, series, column_name, index_level, callable… вы называете это
Например, вы можете сделать:
df = df.groupby(
[
'Resolution', df.FrameRate//0.02 * 0.02,
pd.cut(df.Runtime, bins=[45, 90, 95, 100, 120])
]
).File.apply(list)
Который вернет фрейм данных с уникальным мультииндексом из 3 уровней и одного столбца, каждая строка которого содержит список имен файлов.
Вы также можете получить полные строки для каждой группы, если по какой-либо причине с другими данными вы хотите разделить один df на множество и оставить его таким образом.
for group_id, group_rows in df.groupby(...):
# group id are tuples each with a unique combination of the grouping vectors
# group_rows is a df of the matching rows, with the same columns as df
Комментарии:
1. где должно быть закрытие
]
? Я получаюinvalid syntax
сверху (без закрытия]
).2. Когда я набирал текст, все было в порядке, я внес правку, чтобы более четко показать структуру
3. отлично, спасибо за обновление. Всего пара вопросов по ответу: что такое
.File
— я никогда раньше этого не видел? И, во-вторых, зачем//0.02 *0.02
взламывать?4. Ко всем столбцам фрейма данных можно обращаться как к атрибутам (если только имя столбца не является определенным методом для df как sum, mean и т.д.), возвращающим ряд. Разделение по этажам было просто примером использования модифицированных рядов в качестве группера без необходимости изменения исходного df.
5. о, я понимаю! Я думал,
.File
что это метод для фрейма данных, но я вижу, что это всего лишь поле, которое у меня есть… теперь это имеет гораздо больше смысла.