Добавление дополнительных данных в каждую строку в H2OFrame
Я работаю с огромным H2OFrame
(~150gb, ~200 миллионов строк), которыми мне нужно немного манипулировать. Чтобы быть более конкретным: я должен использовать кадры ip
столбец, чтобы найти местоположение / названия городов для каждого IP и добавить эту информацию в каждую из строк кадра.
Преобразование фрейма в простой объект Python и локальное управление им не подходит из-за огромного размера фрейма. Так что я надеялся, что смогу использовать мой кластер H2O для создания нового H2OFrame city_names
используя оригинальные кадры ip
столбец, а затем объединить оба кадра.
Мой вопрос похож на вопрос, поставленный здесь, и из ответа на этот вопрос я понял, что в H2O нет способа выполнять сложные манипуляции с каждой из строк кадра. Это действительно так? H2OFrame
"s apply
В конце концов, функция принимает только лямбду без пользовательских методов.
Один из вариантов, о котором я подумал, - это использовать Spark/Sparkling Water
для такого рода манипулирования данными, а затем преобразовать искровой кадр в H2OFrame для выполнения операций машинного обучения. Однако, если возможно, я бы предпочел избежать этого и использовать только H2O, не в последнюю очередь из-за накладных расходов, которые создает такое преобразование.
Итак, я думаю, это сводится к следующему: есть ли способ сделать такого рода манипуляции, используя только H2O? И если нет, то есть ли другой вариант сделать это без необходимости изменения архитектуры моего кластера (т.е. без необходимости превращать мой кластер H2O в кластер с газированной водой?)
2 ответа
Да, при использовании apply с H2OFrame вы не можете передать функцию, вместо этого принимается только лямбда. Например, если вы попытаетесь передать функцию tryit, вы получите следующую ошибку, показывающую ограничение:
H2OValueError: Argument `fun` (= <function tryit at 0x108d66410>) does not satisfy the condition fun.__name__ == "<lambda>"
Как вы уже знаете, Sparkling Water - это еще один вариант, когда все данные сначала копируются в режиме Spark, а затем отправляете данные в H2O для ML.
Если вы хотите придерживаться H2O как есть, тогда вы можете просто циклически перебирать кадры данных, чтобы обрабатывать элементы по-своему. Следующая опция может занять немного времени, в зависимости от ваших данных, однако она не требует перемещения вашей среды.
- Создайте новый фрейм H2O, выбрав только свой столбец "ip" и добавив к нему местоположение, город и другие пустые столбцы с помощью NA.
- Прокрутите все значения ip и, основываясь на "ip", найдите местоположение / город и добавьте местоположение, город и другие значения столбца в существующие столбцы.
- Наконец, cbind новый h2oFrame с оригинальным H2OFrame
- Проверьте правильность слияния со 100% соответствием для столбцов "ip" и "ip0", а затем удалите один из дубликатов столбца "ip0".
- Удалите другой дополнительный H2OFrame, чтобы сохранить память
Если ваш алгоритм ip -> city является таблицей поиска, вы можете создать его как фрейм данных, а затем использовать h2o.merge
, Например, это видео (начиная с отметки 59 минут) показывает, как объединить данные о погоде с данными авиакомпаний.
Я полагаю, что для IP-адресов вы можете сначала обрезать до первых двух или трех частей.
Если у вас нет таблицы поиска, становится интересно узнать, быстрее ли превратить сложный алгоритм в это дерево поиска и выполнить h2o.merge
или продолжайте загружать ваши огромные данные в пакетном режиме, запускать локально в клиенте, загружать пакет ответов и делать h2o.cbind
в конце.
Кстати, классный и модный подход заключается в том, чтобы собрать 1 миллион ваших IP-адресов, найти правильный ответ на клиенте, чтобы создать набор данных для обучения, а затем использовать H2O для построения модели машинного обучения. Вы можете использовать h2o.predict()
создать новую колонку города в ваших реальных данных. (Тем не менее, сначала нужно хотя бы разделить IP-адрес на 4 столбца.) (Моя догадка о том, что глубокий случайный лес подойдет лучше всего... но я бы определенно немного поэкспериментировал.)