Эффективно добавить столбец в Pandas DataFrame со значениями из другого DataFrame - PullRequest
0 голосов
/ 05 октября 2018

У меня есть простая база данных, состоящая из 2 таблиц (скажем, «Предметы» и «Пользователи»), где столбец «Пользователи» - это их Идентификатор пользователя , столбец «Элементы» - это их Item_ID и другой столбец Предметов - это внешний ключ для идентификатора пользователя , например:

Items                                       Users
Item_ID  Value_A  Its_User_ID ...           User_ID  Name  ...
1        35       1                         1        Alice
2        991      1                         2        John
3        20       2  

Представьте, что я хочу денормализовать эту базу данных, т.е. ядобавление значения столбца Name из таблицы Users в таблицу Items для повышения производительности при запросе данных.Мое текущее решение заключается в следующем:

items['User_Name'] = pd.Series([users.loc[users['User_ID']==x, 'Name'].iloc[0] 
                     for x in items['Its_User_ID']])

То есть я добавляю столбец в виде серии Панд, построенной из списка понимания, который использует .loc [] для извлеченияимена пользователей с определенным идентификатором и .iloc [0] для получения первого элемента выбора (который является единственным, потому что идентификаторы пользователей уникальны).

Но этоРешение действительно медленно для больших наборов предметов.Я выполнил следующие тесты:

  • Для 1000 элементов и ~ 200K пользователей: 20 секунд.
  • Для ~ 400K элементов и ~ 200K пользователей: 2,5 часа.(и это реальный размер данных).

Поскольку этот подход является столбцовым, его время выполнения увеличивается мультипликативно на количество столбцов, для которых я делаю этот процесс, и получает слишком много времени-дорого.Хотя я не пробовал использовать циклы для , чтобы заполнять новую серию строк за строкой, я ожидаю, что это должно быть намного дороже.Есть ли другие подходы, которые я игнорирую?Есть ли возможное решение, которое займет несколько минут вместо нескольких часов?

Ответы [ 2 ]

0 голосов
/ 05 октября 2018

Используйте высокопроизводительные операции с базой данных, предоставляемые Panda, см. здесь .

Например:

pd.merge(items, users, left_on='Its_User_ID', right_on='User_ID')
0 голосов
/ 05 октября 2018

Думаю, было бы проще, если бы вы использовали таблицу merges .

items.merge(users[['User_ID', 'Name']], left_on='Its_User_ID', right_on='User_ID', how='left')

Это добавит столбец Name к новому набору данных, который вы, конечно, можете переименовать позже.,Это будет намного эффективнее, чем выполнение операции с помощью цикла for по столбцам.

...