Как использовать строковые ссылки в логических сравнениях - PullRequest
0 голосов
/ 30 января 2019

Я пытаюсь создать цикл для создания множества переменных на основе логических сравнений.Я смотрю на три переменные одновременно и создаю флаги на основе того, имеет ли наблюдение 1,2 или три из этих флагов.

Я получаю ошибку, когда пытаюсь посмотреть на 3 переменные.Как ни странно, он отлично работает с 1 или 2.Я даже пытался использовать одну и ту же переменную дважды (чтобы убедиться, что она не имеет ничего общего с переменной), но это тоже не работает.Это что-то о добавлении третьей переменной.

Создание аналогичного набора данных

results = pd.DataFrame(np.random.randint(0,2,size=(20, 3)), columns=['Pre_BF_2014_Flag', 'BF_2014_Flag', 'XMAS_2014_Flag' ])

Это то, что выглядит как жестко запрограммированное, и это работает

results.loc[(results.Pre_BF_2014_Flag == 1) & (results.BF_2014_Flag == 0) & 
(results.XMAS_2014_Flag == 0), 'Combo_2014_Pre_BF_Only'] = 1 

Я пытаюсьпоместите это в цикл (так как у меня много лет и флагов)

years= [2014, 2015, 2016, 2017, 2018]
var = ['_Flag']

for i in years:
    for k in var:

        results.loc[("results.Pre_BF_" + str(i) + str(k) == 1) & 
("results.BF_" + str(i) + str(k) == 0) & ("results.XMAS_"+ str(i) + 
str(k) == 0), 'Combo_2014_Pre_BF_Only'] = 1 

Это показывает ошибку

KeyError: 'не может использовать один bool для индексации в setitem'

Когда я жестко кодирую это третье условие, оно прекрасно работает.

results.loc[("results.Pre_BF_" + str(i) + str(k) == 1) & ("results.BF_" + str(i) + str(k) == 0) & (results.XMAS_2014_Flag == 0), 'Combo_2014_Pre_BF_Only'] = 1 

Также работает, если я использую эту переменную XMAS в качестве первого или второго условия.Это просто что-то вроде использования 3 условий.

Есть идеи, что здесь происходит?

Ответы [ 2 ]

0 голосов
/ 30 января 2019

Будь осторожен."results.Pre_BF_" + str(i) + str(k) представляет строку , а не серию.Вы не можете использовать векторизованное логическое индексирование со строками.

Вы можете написать свою предполагаемую логику следующим образом:

years= [2014, 2015, 2016, 2017, 2018]
var = ['_Flag']

for i in years:
    for k in var:
        m1 = results[f'Pre_BF_{i}{k}'] == 1
        m2 = results[f'BF_{i}{k}'] == 0
        m3 = results[f'XMAS_{i}{k}'] == 0
        results.loc[m1 & m2 & m3, f'Combo_{i}_Pre_BF_Only'] = 1

Лучшей идеей является создание логического ряда с помощью прямого присваивания:

        results[f'Combo_{i}_Pre_BF_Only'] = m1 & m2 & m3
0 голосов
/ 30 января 2019
results['Pre_BF_2014_Flag'] & results['BF_2014_Flag'] & results['XMAS_2014_Flag']

Или

from functools import reduce
results.apply(lambda col: reduce(lambda p,q: p & q, col), axis=1)
...