2016-07-26 4 views
1

Ниже мой код. Я пытаюсь проанализировать DataFrame и хранить совпадения компаний. Однако оператор if всегда возвращает true, и все сохраняется в dataframe current_customers, хотя около 10 из моих 150 строк имеют значение> 97. Ниже мой код является образцом моих данных.Сложный оператор if возвращает все верно

current_customers = pandas.DataFrame() 
potential_customers = pandas.DataFrame() 
for i in range(0, len(FDA_useful_companies_bing)): 
    if combined_data['match token sort'].iloc[i] or combined_data['match ratio'].iloc[i] or combined_data['match partial ratio'].iloc[i] > 97: 
     current_customers = current_customers.append(combined_data.ix[i,4::]) 
    else: 
     potential_customers = potential_customers.append(combined_data.ix[i,4::]) 

Пример моих данных

Company        City   State  ZIP  FDA Company     FDA City   FDA State FDA ZIP Token sort ratio    match token sort Ratio       match ratio Partial Ratio   match partial ratio 
NOVARTIS       Larchwood  IA   51241 HELGET GAS PRODUCTS INC  Kansas City   MO   64116 AIR PRODUCTS CHEMICALS INC 73    OCEANIC MEDICAL PRODUCTS INC 59    LUCAS INC    78 
BOEHRINGER INGELHEIM VETMEDICA INC Sioux Center IA   51250 SOUTHWEST TECHNOLOGIES INC North Kansas City MO   64116 SOUTHWEST TECHNOLOGIES  100    SOUTHWEST TECHNOLOGIES   92    SOUTHWEST TECHNOLOGIES 100 

EDIT: Кроме того, если есть более эффективный способ сделать это, я хотел бы услышать.

+0

Я не считаю, что мой дубликат, потому что мой связано с тем, как pandas dataframe работает с оператором if. – Jstuff

+0

Нет, проблема стандартная Python. 'foo или bar или baz> 97' всегда будет возвращать значение True для значений, отличных от 0, foo и bar. –

+0

Вы правы. Я не понял ошибку. – Jstuff

ответ

2

IIUC вы можете просто сделать:

current_customer = combined_data[(combined_data[['match token sort','match ratio','match partial ratio']] > 97).any(axis=1)] 

potential_customer = combined_data[(combined_data[['match token sort','match ratio','match partial ratio']] <= 97).all(axis=1)] 

Что вы пробовали короткие замыкания, поскольку любое ненулевое значение будет вычисляться True, как это не сравниваю все члены против последнего числового значения, как вы ожидали:

if combined_data['match token sort'].iloc[i] or combined_data['match ratio'].iloc[i] or combined_data['match partial ratio'].iloc[i] > 97: 

Так что это эквивалентно:

if some_val or another_val or last_val > 95 

так вот если some_val ненулевая или another_val является non_zero тогда весь оператор вычисляет True

Вы можете увидеть это в упрощенном случае:

In [83]: 
x = 1 ​ 
if 5 or x > 95: 
    print('True') 
else: 
    print('False') 

это выходы:

True 

Только с одним сравнением:

In [85]: 
if 5 > 95: 
    print('True') 
else: 
    print('False') 

outp UTS:

False 

, но с каждым значением по сравнению с целевым значением:

In [87]: 
x=1 
if 5 > 95 or x > 95: 
    print('True') 
else: 
    print('False') 

это сейчас печатает:

False 

но реальная точка здесь является не петля на всех, вы может быть выбран из вашего df, передав список интересующих количеств, затем вы можете сравнить весь df с вашим скалярным значением и использовать any(axis=1) для генерации булевой маски и использовать ее для маскировки df для повторной установки n вы, текущие клиенты, затем инвертируете сравнение и используете all(axis=1), чтобы найти строки, в которых ни один из столбцов не удовлетворяет вашему предыдущему сравнению, чтобы отфильтровать df для потенциальных клиентов.

+0

А я знал, что должен быть более простой способ сделать это. Я ценю время, чтобы объяснить, почему он всегда оценивается как истинный с вашим примером! – Jstuff

+0

Команда 'axis = 1' трудно понять. – Jstuff

+1

Параметр 'axis = 1' указывает, что мы хотим, чтобы сравнение выполнялось по строкам, а не по столбцу, которое было бы' axis = 0', вы должны попробовать изменить его с «1» на «0», чтобы увидеть разницу – EdChum

0

Ваша проблема в том, если заявление, как вы подозревали:

if combined_data['match token sort'].iloc[i] or combined_data['match ratio'].iloc[i] or combined_data['match partial ratio'].iloc[i] > 97: 

Вы спрашиваете, если выражение «combined_data [„соответствует токенов рода“] iloc [я]» это правда, что это число> 0, поэтому это значение truthey в соответствии с Python. Таким образом, все выражение возвращает True.

Я добавлю скобку, чтобы сделать его более ясным, как Python интерпретирует эту строку кода:

if (combined_data['match token sort'].iloc[i]) or 
    (combined_data['match ratio'].iloc[i]) or 
    (combined_data['match partial ratio'].iloc[i] > 97): 

Python оценивает заявления в скобках отдельно, и Python considers any non-zero number to be a "truthey" value, и, таким образом, используется в качестве условного это возвращает значение True. Вот скорректированное выражение:

if (combined_data['match token sort'].iloc[i]) > 97 or 
     (combined_data['match ratio'].iloc[i]) > 97 or 
     (combined_data['match partial ratio'].iloc[i] > 97): 

Теперь Python будет выполнять каждую операцию как операцию сравнения, как вы планировали.

Смежные вопросы