Может ли pd.DataFrame.apply добавлять данные, возвращаемые лямбда-функцией? - PullRequest
1 голос
/ 08 октября 2019

Я пытаюсь преобразовать этот код -

    for item in data['item'].unique():
     response = process_item(item) # returns List[Dict[Text, Optional[int]]]
     response = pd.DataFrame(response)
     response['item'] = item
     final_response = final_response.append(response)

во что-то вроде -

    data = data[['item']].drop_duplicates().reset_index(drop=True)
    final_response = data[['item']].apply(lambda x: process_item(x))
    final_response['item'] = data['item']

Идея состоит в том, чтобы позже использовать dask для параллельной обработки apply на фрейме данных.

Я попытался вернуть pd.DataFrame из process_item, но я получил ValueError: Если вы используете все скалярные значения, вы должны передать индекс

, ответ выглядит примерно так -

   A       B         C
0  456  foo bar     123.0

Как разрешить ошибку ValueError, и мое предположение о том, что применить, добавит вывод df из process_item в final_response правильно?

EDIT : добавлены примеры данных

Обтекание выводаfrom process_item в pd.Series -

#output from process_item
{'A': [456, 789], 'B': ['foo bar', 'dog bar'], 'C': [123.0, 160.0]}

#printing ouput in pd.Series
A        [456, 789]
B        [foo bar, dog bar]
C        [123.0, 160.0]

#Adding a new 'item' column
          A             B           C                    item
0  [456, 789]  [foo bar, dog bar]  [123.0, 160.0]         bar

Ниже приведен фрагмент первого кода -

#output from process_item
{'A': [456, 789], 'B': ['foo bar', 'dog bar'], 'C': [123.0, 160.0]}

#output from process_item in pd.DataFrame
    A      B          C
0  456  foo bar     123.0
1  789  dog bar     160.0

#Adding a new 'item' column
            A              B               C           item
0          456          foo bar          123.0         bar
1          789          dog bar          160.0         bar

Мне нужен элемент, добавленный согласно второму примеру.

РЕДАКТИРОВАТЬ (решено): я наконец смог заставить это работать с некоторыми изменениями в функции split_dataframe_rows, совместно используемой @yugandhar. 1. Вычисление max_split - это было вычисление длины вновь добавленного столбца 'item', в котором был 'bar', то есть с оценкой 3, в то время как другие списки содержали только два элемента, добавили проверку типа. 2. split_rows[column_selector].pop(0) выдавал ошибку для столбца 'item' о том, что объект str не имеет атрибута pop. Итак, добавлена ​​проверка, чтобы сделать это, только если это был список, в противном случае просто назначьте. Протестировано с вашим обновленным решением, а также работает отлично. Не уверен, почему эти проблемы не возникли в colab, может быть разница версий Python или что-то в этом роде. Я пытался взорваться, но у меня это тоже не работает, наверное, я не использую панды 0.25. Я буду продолжать искать лучшие способы сделать раскол.

Ответы [ 2 ]

0 голосов
/ 09 октября 2019

Рассмотрим понимание списка для построения списка фреймов данных, которые должны быть объединены в конце:

dfs = [(pd.DataFrame(process_item(i)) 
          .assign(item = i) 
       ) for i in data['item'].unique()]

final_df = pd.concat(df_list, ignore_index=True)
0 голосов
/ 08 октября 2019

Если я правильно понимаю, вам нужно внести следующие изменения:
Вернуть pd.Series вместо pd.DataFrame,
использовать data ['item'] для получения значений (это то, что вам нужно дляприменить) в столбце и
data [['item']], чтобы получить фрейм данных со столбцами индекса и элемента
Рабочий раствор

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