Как отсортировать группы панд по (несколько/всем) значениям групп?Python

Программы на Python
Ответить
Anonymous
 Как отсортировать группы панд по (несколько/всем) значениям групп?

Сообщение Anonymous »

Я пытаюсь выполнить довольно сложную операцию группировки и сортировки в pandas. Я хочу отсортировать группы по их значениям в порядке возрастания, используя при необходимости последовательные значения для тай-брейков.
Я прочитал аналогичный вопрос в фрейме данных Pandas: Как сортировать группы по самому раннему времени группы, но он использует только минимальное значение в каждой группе для сортировки и, следовательно, не обрабатывает случай, когда две группы имеют одинаковое минимальное значение, но различаются другими значениями.
Аналогично, pandas groupby, затем сортировка внутри групп обсуждает сортировку внутри группы, но не сортировку между группами, чего я и добиваюсь.
В качестве конкретного примера рассмотрим следующий фрейм данных:

Код: Выделить всё

df = pd.DataFrame({"pool": [5, 1, 9, 9, 5, 7, 7, 7, 9, 1, 5],
"arrival":[227, 60, 60, 88, 55, 55, 276, 46, 46, 35, 35]})
Я хочу отсортировать пулы по прибытии, чтобы результирующий фрейм данных был следующим:

Код: Выделить всё

    pool  arrival
10     5       35
4      5       55
0      5      227
9      1       35
1      1       60
7      7       46
5      7       55
6      7      276
8      9       46
2      9       60
3      9       88
Мне удалось сделать это с помощью следующего кода:

Код: Выделить всё

# create column to indicate order of values in each group
df = df.sort_values("arrival")
df["order"] = df.groupby("pool")["arrival"].cumcount()

# use 'order' column to make columns for each arrival position
df["first"] = df["second"] = df["third"] = np.nan
df.loc[df["order"] == 0,"first"] = df.loc[df["order"] == 0,"arrival"]
df.loc[df["order"] == 1,"second"] = df.loc[df["order"] == 1,"arrival"]
df.loc[df["order"] == 2,"third"] = df.loc[df["order"] == 2,"arrival"]

# propagate the values to every member of the group
df[["first","second","third"]] = df.groupby("pool")[["first","second","third"]].transform("max")

# for groups with less than three members, fill the values with previous ones
df["second"] = df["second"].fillna(df["first"])
df["third"] = df["third"].fillna(df["second"])

# sort by the arrival position columns, then drop all the helper columns
df = df.sort_values(["first","second","third","pool"]).drop(columns=["first","second","third","order"])
Это работает, но не очень масштабируемо для пулов с большим количеством поступлений (20+). Я убежден, что должен быть лучший способ, но не могу понять, как это сделать.
Я также пробовал объединить функции Transform и nth, как обсуждалось в разделе «Использование преобразования вместе с nth», но, вопреки принятому ответу на этот вопрос, попытка передать «nth» в groupby.transform вызывает ValueError: «nth» не является допустимым именем функции для преобразования (имя), поскольку nth может не возвращает ни одного значения или несколько значений для данной группы, и преобразование не может обработать эти случаи.

Подробнее здесь: https://stackoverflow.com/questions/797 ... the-groups
Ответить

Быстрый ответ

Изменение регистра текста: 
Смайлики
:) :( :oops: :roll: :wink: :muza: :clever: :sorry: :angel: :read: *x)
Ещё смайлики…
   
К этому ответу прикреплено по крайней мере одно вложение.

Если вы не хотите добавлять вложения, оставьте поля пустыми.

Максимально разрешённый размер вложения: 15 МБ.

Вернуться в «Python»