2025, Dec 15 03:01
Сортировка и фильтрация словарей в DolphinDB: рабочие практики
Почему словари DolphinDB неупорядочены и как сортировать и фильтровать их по значениям через таблицу. Примеры кода, ordered=true и надежная замена argsort.
Фильтрация и сортировка данных в формате ключ–значение в словарях Python — дело простое, а вот в DolphinDB к этому стоит подойти немного иначе. Частая ошибка — использовать привычные инструменты вроде argsort и применять их к значениям словаря. В DolphinDB словари по умолчанию не имеют порядка и не предоставляют argsort в стиле Python/NumPy. Ниже показан компактный, пригодный для продакшена способ добиться того же результата: отобрать города с населением свыше 10 миллионов и отсортировать их по численности по убыванию.
Проблема в двух словах
Задача предельно проста: создать словарь численности городов, выбрать мегаполисы и отсортировать по населению. На Python это читается почти как обычное предложение.
# Создать словарь
metro_stats = {"New York": 8419000, "Tokyo": 13960000, "London": 8900000}
# Найти города с населением > 10 миллионов
mega_cities = {c: n for c, n in metro_stats.items() if n > 10000000}
print("Cities with population > 10M:", mega_cities)
# Отсортировать по численности
rank_cities = dict(sorted(metro_stats.items(), key=lambda p: p[1], reverse=True))
print("Cities sorted by population:", rank_cities)
Попытка напрямую воспроизвести этот подход в DolphinDB часто приводит к ошибке вокруг argsort.
// 1. Создать словарь
mapCities = dict(["New York", "Tokyo", "London"], [8419000, 13960000, 8900000])
// 2. Отфильтровать города с населением > 10 млн
sel = mapCities.values() > 10000000
megaMap = dict(mapCities.keys()[sel], mapCities.values()[sel])
print("Cities with population > 10M: " + string(megaMap))
// 3. Отсортировать по численности (по убыванию)
valsSorted = mapCities.values().sort(false)
keysSorted = mapCities.keys()[mapCities.values().argsort().reverse()]
mapSorted = dict(keysSorted, valsSorted)
print("Cities sorted by population: " + string(mapSorted))
Что на самом деле не так
Проблема носит концептуальный характер. Словари Python можно отсортировать через sorted и функцию key, зависящую от значений, а в NumPy/Pandas есть argsort для переупорядочивания индексов по значениям. В DolphinDB словари по умолчанию неупорядочены, поэтому даже если вы отдельно отсортируете значения, надёжно восстановить словарь, отсортированный по значениям, индексируя ключи результатом argsort, не получится. К тому же argsort в таком виде здесь недоступен, из‑за чего и возникает ошибка.
Правильный подход в DolphinDB двушаговый. Во‑первых, если важен порядок, создайте упорядоченный словарь. Во‑вторых, чтобы сортировать по значениям, преобразуйте словарь в таблицу, отсортируйте таблицу и соберите упорядоченный словарь из отсортированных столбцов.
Рабочее решение
Ниже приводится реализация, которая повторяет поведение Python, но следует идиомам DolphinDB. Там, где нужно, сохраняется порядок вставки, для фильтрации используется булева маска, а сортировка выполняется через промежуточный шаг с таблицей.
// 1. Построить упорядоченный словарь (сохранить порядок вставки)
metroMap = dict(
["New York", "Tokyo", "London"],
[8419000, 13960000, 8900000],
ordered=true
)
// 2. Булева маска для населения > 10 млн
filt = metroMap.values() > 10000000
bigMap = dict(
metroMap.keys()[filt],
metroMap.values()[filt]
)
print("Cities with population > 10M: " + string(bigMap))
// 3. Сортировка по численности через таблицу и сборка упорядоченного словаря
ds = table(
metroMap.keys() as cityName,
metroMap.values() as popCount
)
ds.sortBy!(`popCount, false)
rankedMap = dict(
ds.cityName,
ds.popCount,
ordered=true
)
print("Cities sorted by population: " + string(rankedMap))
Почему это важно
Осознание того, что словари DolphinDB по умолчанию неупорядочены, экономит время и помогает избежать неожиданных результатов, когда вы рассчитываете на порядок. «Заход через таблицу» для сортировки — не костыль, а идиоматичный способ использовать сильные стороны DolphinDB в колоночных операциях и при этом сохранить семантику словаря для быстрых поисков. Такой подход также оставляет фильтрацию векторизованной и предсказуемой — что особенно важно при росте объёмов данных.
Итоги
Если нужен порядок, указывайте его явно через ordered=true. Для фильтрации используйте булевы маски по значениям. Чтобы сортировать по значениям, преобразуйте словарь в таблицу, отсортируйте её и восстановите упорядоченный словарь из отсортированных столбцов. Если что‑то ведёт себя странно, быстро проверьте типы и формы с помощью print и близких по смыслу проверок, чтобы понять, что именно проходит через ваш код. Придерживаясь этих практик, вы получите понятный и устойчивый код при переносе привычных сценариев работы со словарями из Python в DolphinDB.