Как это сделать в пандах:
У меня есть функция extract_text_features
для одного текстового столбца, возвращающая несколько выходных столбцов. В частности, функция возвращает 6 значений.
Функция работает, однако, похоже, не существует какого-либо правильного возвращаемого типа (pandas DataFrame / numpy array / Python list), чтобы выходные данные могли быть правильно назначены df.ix[: ,10:16] = df.textcol.map(extract_text_features)
Так что я думаю, что мне нужно вернуться к итерации с df.iterrows()
, в соответствии с этим ?
ОБНОВЛЕНИЕ: Итерация с df.iterrows()
, по крайней мере, в 20 раз медленнее, поэтому я сдался и разделил функцию на шесть отдельных .map(lambda ...)
вызовов.
ОБНОВЛЕНИЕ 2: этот вопрос был задан около v0.11.0 . Следовательно, большая часть вопроса и ответов не слишком актуальны.
df.ix[: ,10:16]
. Я думаю, что вы будете использоватьmerge
ваши функции в наборе данных.apply
Ответы:
Основываясь на ответе пользователя 1827356, вы можете выполнить задание за один проход, используя
df.merge
:РЕДАКТИРОВАТЬ: Обратите внимание на огромное потребление памяти и низкую скорость: https://ys-l.github.io/posts/2015/08/28/how-not-to-use-pandas-apply/ !
источник
Я обычно делаю это, используя
zip
:источник
temp = list(zip(*df['num'].map(powers))); for i, c in enumerate(columns): df[c] = temp[c]
for i, c in enumerate(columns): df[c] = temp[i]
. Благодаря этому я действительно получил цельenumerate
: Dzip(*df['col'].map(function))
- это правильный путь.Это то, что я сделал в прошлом
Редактирование для полноты
источник
df[['col1', 'col2']] = df['col3'].apply(lambda x: pd.Series('val1', 'val2'))
Это правильный и самый простой способ сделать это для 95% случаев:
источник
pd.Series({k:v})
и сериализовать присваивание столбца, как в ответе Эвана?В 2018 году я использую
apply()
с аргументомresult_type='expand'
источник
pd.Series
что всегда хорошо в отношении проблем с производительностьюdf.apply
возвращает adict
, столбцы получат имена в соответствии с ключами.Просто используйте
result_type="expand"
источник
Сводка: если вы хотите создать только несколько столбцов, используйте
df[['new_col1','new_col2']] = df[['data1','data2']].apply( function_of_your_choosing(x), axis=1)
Для этого решения количество создаваемых вами новых столбцов должно быть равно количеству столбцов, которые вы используете в качестве входных данных для функции .apply (). Если вы хотите сделать что-то еще, взгляните на другие ответы.
подробности Допустим, у вас есть двухколонный фрейм данных. Первый столбец - это рост человека, когда ему 10 лет; второй - рост человека, когда ему 20 лет.
Предположим, вам нужно рассчитать как среднее значение высоты каждого человека, так и сумму высот каждого человека. Это два значения в каждой строке.
Вы можете сделать это с помощью следующей функции, которая скоро будет применена:
Вы можете использовать эту функцию так:
(Для ясности: эта функция применяет значения из каждой строки в установленном кадре данных и возвращает список.)
Однако, если вы сделаете это:
вы создадите 1 новый столбец, который содержит списки [среднее, сумма], которых вы, вероятно, хотели бы избежать, потому что для этого потребуется еще одна лямбда / аппликация.
Вместо этого вы хотите разбить каждое значение на отдельный столбец. Для этого вы можете создать два столбца одновременно:
источник
df["mean"], df["sum"] = df[['height_at_age_10','height_at_age_20']] .apply(mean_and_sum(x),axis=1)
return pd.Series([mean,sum])
Для меня это сработало:
Вход df
функция
Создайте 2 новых столбца:
Вывод:
источник
Я рассмотрел несколько способов сделать это, и метод, показанный здесь (возвращающий серию панд), кажется, не самый эффективный.
Если мы начнем с большого фрейма случайных данных:
Пример, показанный здесь:
Альтернативный метод:
По моим расчетам, гораздо эффективнее взять серию кортежей, а затем преобразовать их в DataFrame. Мне было бы интересно услышать мнение людей, хотя, если есть ошибка в моей работе.
источник
Принятое решение будет очень медленным для большого количества данных. Решение с наибольшим количеством голосов является немного сложным для чтения, а также медленным с числовыми данными. Если бы каждый новый столбец можно было вычислить независимо от других, я бы просто назначил каждый из них напрямую, не используя
apply
.Пример с поддельными символами
Создать 100 000 строк в DataFrame
Допустим, мы хотели извлечь некоторые текстовые функции, как было сделано в исходном вопросе. Например, давайте извлечем первый символ, посчитаем вхождение буквы «е» и заглавную фразу.
Задержки
Удивительно, но вы можете повысить производительность, просматривая каждое значение
Еще один пример с поддельными числовыми данными
Создайте 1 миллион случайных чисел и протестируйте
powers
функцию сверху.Назначение каждого столбца в 25 раз быстрее и очень читабельно:
Я сделал аналогичный ответ с более подробной информацией о том, почему,
apply
как правило, это не тот путь.источник
Опубликовали тот же ответ в двух других похожих вопросах. Я предпочитаю делать это, чтобы обернуть возвращаемые значения функции в серию:
А затем используйте apply следующим образом для создания отдельных столбцов:
источник
вы можете вернуть всю строку вместо значений:
где функция возвращает строку
источник
extract_text_features
к каждому столбцу df, только к текстовому столбцуdf.textcol
Это сработало для меня. Новый столбец будет создан с обработанными данными старого столбца.
источник