2016-10-25 2 views
1

У меня есть лист Excel с более чем ста столбцами. Мне нужно отфильтровать около пяти из них, чтобы увидеть, какие столбцы имеют «нет» в одной из ячеек. Есть ли способ, чтобы отфильтровать несколько столбцов с едиными критериями поиска, такие как:Pandas filter mulitple columns с одним критерием

no_invoice_filter = df[(df['M1: PL - INVOICED']) & (df['M2: EX - INVOICED']) & (df['M3: TEST DEP - INVOICED']) == 'No'] 

Как oppossed в отдельно выписывать, если каждый столбец не равен «нет»

ошибку в коде выше:

TypeError: unsupported operand type(s) for &: 'str' and 'bool' 

ответ

1

Вы можете сделать:

df[(df[['M1: PL - INVOICED','M2: EX - INVOICED','M3: TEST DEP - INVOICED']] == 'No')] 

Таким образом, вы в основном передать список перевалы интереса и сравнить только эти столбцы против вашего скалярного значения, если вы после того, как ' нет»появляться в любом месте, то используйте any(axis=1)

In [115]: 
df = pd.DataFrame({'a':'no', 'b':'yes', 'c':['yes','no','yes','no','no']}) 
df 

Out[115]: 
    a b c 
0 no yes yes 
1 no yes no 
2 no yes yes 
3 no yes no 
4 no yes no 

С any(axis=1) тогда он возвращает все строки, в которых не отображается в любом из перевалов интересов:

In [133]:  
df[(df[['a','c']] == 'no').any(axis=1)] 

Out[133]: 
    a b c 
0 no yes yes 
1 no yes no 
2 no yes yes 
3 no yes no 
4 no yes no 

Вы также можете использовать маску, чтобы отбросить строки NaN для определенного столбца с использованием dropna

In [132]:  
df[df[['a','c']] == 'no'].dropna(subset=['c']) 

Out[132]: 
    a b c 
1 no NaN no 
3 no NaN no 
4 no NaN no 
+0

Хмм, если использовать 'any()' it return 'IndexingError: Unalignable boolean Series key предоставлен' – jezrael

+0

@jezrael true, я добавил пример использования, где вы можете выборочно отбросить строки' NaN' для подмножества столбцов – EdChum

+0

Спасибо, что казалось работал. Я попытался что-то подобное, но пропустил двойные квадратные скобки, и я даже не знал о .any (axis = 1). @J – King

1

Вы должны использовать подмножество столбцов с any, по крайней мере, один No в колонках:

df[(df[['M1: PL - INVOICED','M2: EX - INVOICED','M3: TEST DEP - INVOICED']] == 'No') 
     .any(axis=1)] 

Пример:

df = pd.DataFrame({'M1: PL - INVOICED':['a','Yes','No'], 
        'M2: EX - INVOICED':['Yes','No','b'], 
        'M3: TEST DEP - INVOICED':['s','a','No']}) 

print (df) 
    M1: PL - INVOICED M2: EX - INVOICED M3: TEST DEP - INVOICED 
0     a    Yes      s 
1    Yes    No      a 
2    No     b      No 

print ((df[['M1: PL - INVOICED','M2: EX - INVOICED','M3: TEST DEP - INVOICED']] == 'No')) 
    M1: PL - INVOICED M2: EX - INVOICED M3: TEST DEP - INVOICED 
0    False    False     False 
1    False    True     False 
2    True    False     True 

print ((df[['M1: PL - INVOICED','M2: EX - INVOICED','M3: TEST DEP - INVOICED']] == 'No') 
      .any(axis=1)) 
0 False 
1  True 
2  True 
dtype: bool 


print (df[(df[['M1: PL - INVOICED','M2: EX - INVOICED','M3: TEST DEP - INVOICED']] == 'No') 
      .any(1)]) 

    M1: PL - INVOICED M2: EX - INVOICED M3: TEST DEP - INVOICED 
1    Yes    No      a 
2    No     b      No 
+0

ОП, указанным для решения без явного именования каждого столбца сравнить с Нет как ваше первое решение – EdChum

+0

@EdChum - спасибо. Я добавляю только второе решение. – jezrael

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