Медленный цикл агрегирования строк и столбцов - PullRequest
0 голосов
/ 26 ноября 2018

У меня есть DataFrame со столбцом с именем «UserNbr» и столбцом с именем «Spclty», который состоит из таких элементов:

[['104', '2010-01-31'], ['215', '2014-11-21'], ['352', '2016-07-13']]

, где может быть 0 или более элементов в списке.

Некоторые ключи UserNbr появляются в нескольких строках, и я хочу свернуть каждую такую ​​группу в одну строку, чтобы Spclty содержал все уникальные диктовки, подобные приведенным в списке, приведенном выше.

Чтобы сэкономить накладные расходы при добавлении в DataFrame, я добавляю каждую выходную строку в список, а не в DataFrame.

Мой код работает, но для его работы требуется 0,7 млн ​​строк ввода.(На самом деле, я никогда не мог держать свой ноутбук открытым достаточно долго, чтобы он мог завершить работу.)

Есть ли лучший способ объединиться в такую ​​структуру, возможно, с использованием библиотеки, которая предоставляет больше данныхизменяя параметры вместо того, чтобы зацикливаться на UserNbr?(В R я использовал бы библиотеки data.table и dplyr.)

# loop over all UserNbr: 
#   consolidate specialty fields into dict-like sets (to remove redundant codes);
#   output one row per user to new data frame
out_rows = list() 
spcltycol = df_tmp.column.get_loc('Spclty')                
all_UserNbr = df_tmp['UserNbr'].unique()
for user in all_UserNbr:
    df_user = df_tmp.loc[df_tmp['UserNbr'] == user]
    if df_user.shape[0] > 0:   
        open_combined = df_user_open.iloc[0, spcltycol]   # capture 1st row
        for row in range(1, df_user.shape[0]):       # union with any subsequent rows
            open_combined = open_combined.union(df_user.iloc[row, spcltycol])
        new_row = df_user.drop(['Spclty', 'StartDt'], axis = 1).iloc[0].tolist()
        new_row.append(open_combined)
        out_rows.append(new_row)

# construct new dataframe with no redundant UserID rows:
df_out = pd.DataFrame(out_rows, 
                      columns = ['UserNbr', 'Spclty'])
# convert Spclty sets to dicts:
df_out['Spclty'] = [dict(df_out['Spclty'][row]) for row in range(df_out.shape[0])]

Преобразование в dict избавляет от специальностей, которые повторяются между строками. В выходных данных значение Spclty должно выглядеть следующим образомthis:

{'104': '2010-01-31', '215': '2014-11-21', '352': '2016-07-13'}

за исключением того, что может быть больше пар ключ-значение, чем в любой соответствующей строке ввода (в результате агрегирования по UserNbr).

1 Ответ

0 голосов
/ 12 декабря 2018

Я снял этот вопрос.

Я надеялся, что существует эффективный способ использования groupby с чем-то другим, но я не нашел примеров со сложной структурой данных, подобных этой, и не получил никакого руководства.

Для тех, кто так же зацикливается на очень медленных проблемах агрегации в Python, я предлагаю перейти к PySpark.Сейчас я решаю эту проблему с помощью блокнота Databricks и продвигаюсь вперед с помощью оконных функций pyspark.sql.window.(Теперь для запуска теста требуется несколько минут, а не часов!)

Частичное решение находится в ответе здесь:

PySpark list () в withColumn () работает толькоодин раз, затем AssertionError: col должно быть столбцом

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...