Векторизованное присвоение флага в датафрейме

1

У меня есть dataframe с наблюдениями, имеющими несколько кодов. Я хочу сравнить коды, представленные в строке со списком. Если в этом списке есть какие-либо коды, я хочу отметить строку. Я могу выполнить это, используя метод itertuples следующим образом:

import pandas as pd
import numpy as np

df = pd.DataFrame({ 'id' : [1,2,3,4,5],
                    'cd1' : ['abc1', 'abc2', 'abc3','abc4','abc5'],
                    'cd2' : ['abc3','abc4','abc5','abc6',''],
                    'cd3' : ['abc10', '', '', '','']})

code_flags = ['abc1','abc6']

# initialize flag column
df['flag'] = 0

# itertuples method

for row in df.itertuples():
    if any(df.iloc[row.Index, 1:4].isin(code_flags)):
       df.at[row.Index, 'flag'] = 1

Результат корректно добавляет столбец flag с соответствующими флагами, где 1 обозначает отмеченную запись.

Однако, по моему фактическому варианту использования, на это уходят часы. Я попытался векторизовать этот подход, используя numpy.where.

df['flag'] = 0 # reset
df['flag'] = np.where(any(df.iloc[:,1:4].isin(code_flags)),1,0)

Который, кажется, оценивает все то же самое. Я думаю, я смущен тем, как векторизация обрабатывает индекс. Я могу удалить точку с запятой и написать df.iloc[1:4] и получить тот же результат.

Я неправильно понимаю, where функция? Является ли моя индексация неправильной и вызывает True оценку для всех случаев? Есть лучший способ сделать это?

  • 1
    np.where((df.iloc[:,1:4].isin(code_flags)).any(1),1,0)
  • 0
    Это чище в дополнение к выполнению задачи. У меня были некоторые дополнительные проблемы с моим реальным набором данных, поскольку моим эквивалентом флаговых кодов была серия, а не список. tolist () исправил это. Запретив более подробные объяснения (я, очевидно, все еще несколько новичок с пандами / numpy) Я буду исключать это как ответ, если вы преобразуете его, @Wen
Показать ещё 1 комментарий
Теги:
pandas
numpy
vectorization

1 ответ

1
Лучший ответ

Использование np.where с .any np.where any(..)

np.where((df.iloc[:,1:4].isin(code_flags)).any(1),1,0) 

Ещё вопросы

Сообщество Overcoder
Наверх
Меню