Быстрый способ получить индекс непустых значений в строке/столбце

Допустим, у нас есть следующий фрейм данных pandas:

df = pd.DataFrame({'a': {0: 3.0, 1: 2.0, 2: None}, 'b': {0: 10.0, 1: None, 2: 8.0}, 'c': {0: 4.0, 1: 2.0, 2: 6.0}})

     a     b    c
0  3.0  10.0  4.0
1  2.0   NaN  2.0
2  NaN   8.0  6.0

Мне нужно получить фрейм данных с именами столбцов всех значений, отличных от NaN, для каждой строки. Я знаю, что могу сделать следующее, что приведет к ожидаемому результату:

df2 = df.apply(lambda x: pd.Series(x.dropna().index), axis=1)

   0  1    2
0  a  b    c
1  a  c  NaN
2  b  c  NaN

К сожалению, это довольно медленно с большими наборами данных. Есть ли более быстрый способ?

Получение индексов строк ненулевых значений каждого столбца также может работать, так как мне просто нужно будет перенести входной фрейм данных. Спасибо.

Инструменты для веб-скрапинга с открытым исходным кодом: Python Developer Toolkit
Инструменты для веб-скрапинга с открытым исходным кодом: Python Developer Toolkit
Веб-скрейпинг, как мы все знаем, это дисциплина, которая развивается с течением времени. Появляются все более сложные средства борьбы с ботами, а...
Библиотека для работы с мороженым
Библиотека для работы с мороженым
Лично я попрощался с операторами print() в python. Без шуток.
Эмиссия счетов-фактур с помощью Telegram - Python RPA (BotCity)
Эмиссия счетов-фактур с помощью Telegram - Python RPA (BotCity)
Привет, люди RPA, это снова я и я несу подарки! В очередном моем приключении о том, как создавать ботов для облегчения рутины. Вот, думаю, стоит...
Пошаговое руководство по созданию собственного Slackbot: От установки до развертывания
Пошаговое руководство по созданию собственного Slackbot: От установки до развертывания
Шаг 1: Создание приложения Slack Чтобы создать Slackbot, вам необходимо создать приложение Slack. Войдите в свою учетную запись Slack и перейдите на...
Учебник по веб-скрапингу
Учебник по веб-скрапингу
Привет, ребята... В этот раз мы поговорим о веб-скрейпинге. Целью этого обсуждения будет узнать и понять, что такое веб-скрейпинг, а также узнать, как...
Тонкая настройка GPT-3 с помощью Anaconda
Тонкая настройка GPT-3 с помощью Anaconda
Зарегистрируйте аккаунт Open ai, а затем получите ключ API ниже.
2
0
59
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Используйте numpy:

m = df.notna()
a = m.mul(df.columns).where(m).to_numpy()
out = pd.DataFrame(a[np.arange(len(a))[:,None], np.argsort(~m, axis=1)],
                   index=df.index)

Выход:

   0  1    2
0  a  b    c
1  a  c  NaN
2  b  c  NaN

тайминги

На 30 тыс. строк x 3 столбца:

# numpy approach
6.82 ms ± 1.56 ms per loop (mean ± std. dev. of 7 runs, 100 loops each)

# pandas apply
7.32 s ± 553 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)

Здравствуйте, mozway, могу я спросить, что [:, None] делает в a[np.arange(len(a))[:, None]]? Фактически он превращает его в трехмерный массив. Но я не мог понять, зачем он нужен здесь.

Anoushiravan R 18.02.2023 19:02

@Anoushiravan это преобразование индексатора диапазона 1D в одиночный столбец 2D. Это простой трюк для индексации массива в сочетании с np.argsort(~m, axis=1).

mozway 18.02.2023 19:30

@mozway Я заметил, что иногда скрипт не сохраняет первоначальный порядок индексов. Есть ли способ исправить это? Спасибо

younggotti 19.02.2023 08:52

Другие вопросы по теме