У меня есть 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
оценку для всех случаев? Есть лучший способ сделать это?
Использование np.where
с .any
np.where
any(..)
np.where((df.iloc[:,1:4].isin(code_flags)).any(1),1,0)
np.where((df.iloc[:,1:4].isin(code_flags)).any(1),1,0)