Кадр данных Polars имеет метод top_k, который можно использовать для выбора строк, содержащих k наибольших значений, при сортировке по столбцу. Например, следующий код выбирает две строки с самой большой и второй по величине записью в столбце val:
df = pl.DataFrame({'grp':['a','a','a','b','b','b'], 'val':[1,2,3,10,20,30], 'etc':[0,1,2,3,4,5]})
grp val etc
str i64 i64
"a" 1 0
"a" 2 1
"a" 3 2
"b" 10 3
"b" 20 4
"b" 30 5
df.top_k(2, by='val')
grp val etc
str i64 i64
"b" 30 5
"b" 20 4
Мой вопрос: как мне получить строки с верхними значениями k для каждой группы? В частности, мне нужна вся строка, а не только значение в столбце val. Я хочу сделать что-то подобное, но это не работает в полярах, потому что в полярах GroupBy нет метода top_k:
df.groupby('grp').top_k(2, by='val') # doesnt work in polars
grp val etc
str i64 i64
"b" 30 5
"b" 20 4
"a" 3 2
"a" 2 1
Мне удалось придумать два способа: один с использованием Map_groups и другой с использованием сортировки. Оба из них нежелательны по соображениям производительности. Map_groups обычно не рекомендуется, поскольку он почти всегда значительно медленнее. Опция сортировки также нежелательна, поскольку для получения верхних k элементов используется более быстрый алгоритм, чем для сортировки (для маленьких k и больших n это в основном O (n) против O (n log n)). Поэтому, хотя приведенное ниже работает, я ищу другие подходы. Есть ли способ напрямую использовать метод top_k с группировкой поляров? Это было бы мое идеальное решение.
# works, but at expense of using map_groups method
df.group_by('grp').map_groups(lambda df: df.top_k(2, by='val'))
grp val etc
str i64 i64
"b" 30 5
"b" 20 4
"a" 3 2
"a" 2 1
# works, but at expense of sorting entire groups
df.group_by('grp').agg(pl.all().sort_by('val', descending=True).head(2)).explode('val','etc')
grp val etc
str i64 i64
"a" 3 2
"a" 2 1
"b" 30 5
"b" 20 4
Кадр данных Polars имеет метод top_k, который можно использовать для выбора строк, содержащих k наибольших значений, при сортировке по столбцу. Например, следующий код выбирает две строки с самой большой и второй по величине записью в столбце val: [code]df = pl.DataFrame({'grp':['a','a','a','b','b','b'], 'val':[1,2,3,10,20,30], 'etc':[0,1,2,3,4,5]})
grp val etc str i64 i64 "a" 1 0 "a" 2 1 "a" 3 2 "b" 10 3 "b" 20 4 "b" 30 5
df.top_k(2, by='val')
grp val etc str i64 i64 "b" 30 5 "b" 20 4 [/code] Мой вопрос: как мне получить строки с верхними значениями k для каждой группы? В частности, мне нужна вся строка, а не только значение в столбце val. Я хочу сделать что-то подобное, но это не работает в полярах, потому что в полярах GroupBy нет метода top_k: [code]df.groupby('grp').top_k(2, by='val') # doesnt work in polars
grp val etc str i64 i64 "b" 30 5 "b" 20 4 "a" 3 2 "a" 2 1 [/code] Мне удалось придумать два способа: один с использованием Map_groups и другой с использованием сортировки. Оба из них нежелательны по соображениям производительности. Map_groups обычно не рекомендуется, поскольку он почти всегда значительно медленнее. Опция сортировки также нежелательна, поскольку для получения верхних k элементов используется более быстрый алгоритм, чем для сортировки (для маленьких k и больших n это в основном O (n) против O (n log n)). Поэтому, хотя приведенное ниже работает, я ищу другие подходы. Есть ли способ напрямую использовать метод top_k с группировкой поляров? Это было бы мое идеальное решение. [code]# works, but at expense of using map_groups method df.group_by('grp').map_groups(lambda df: df.top_k(2, by='val'))
grp val etc str i64 i64 "b" 30 5 "b" 20 4 "a" 3 2 "a" 2 1 [/code] [code]# works, but at expense of sorting entire groups df.group_by('grp').agg(pl.all().sort_by('val', descending=True).head(2)).explode('val','etc')
grp val etc str i64 i64 "a" 3 2 "a" 2 1 "b" 30 5 "b" 20 4 [/code] [list] [*][code]df.group_by('grp').top_k(2, by='val')[/code], который не работает в полярах. [*][code]df.group_by('grp').map_groups(lambda df: df.top_k(2, by='val'))[/code], который работает за счет использования карт_групп [*][code]df.group_by('grp').agg(pl.all().sort_by('val', descending=True).head(2)).explode('val','etc')[/code], который работает за счет сортировки [/list]
Данные, с которыми я работаю:
data (140631115432592), ndim: 2, size: 3947910, shape: (232230, 17)
VIN (1-10) object
County object
City object
State object
Postal Code float64
Model Year int64
Make object
Model object
Electric Vehicle Type object...
Файл df содержит 100 миллионов строк, а столбцов group_by — около 25–30. Есть ли способ ускорить эту операцию отсюда? или это лучшее, что я могу получить.
import polars as pl
import numpy as np
Это распечатывает 10 наихудших средних значений в DataFrame (этот флаг Data Frame был построен с помощью AGG, поэтому он имеет многоуровневое имя столбца).
worst = rcresult.sort_values(by=('resolvetime', 'mean') ,ascending=False).head(10)...