Сравните значения Boolean Row в нескольких столбцах в Pandas, используя &/np.where()/np.any()

У меня есть кадр данных, который выглядит так:

   a A  a B  a C  a D  a E  a F  p A  p B  p C  p D  p E  p F
0    0    0    0    0    0    0    0    0    0    0    0    0
1    1    0    0    0    0    0    0    0    0    0    0    0
2    0    1    0    0    0    0    0    0    1    0    0    0
3    0    0    1    0    0    1    0    0    0    0    0    0
4    0    0    0    1    0    1    0    0    0    0    0    0
5    0    0    0    0    1    0    0    0    0    0    0    0
6    0    0    0    0    0    0    1    0    0    0    0    0

df = pd.DataFrame({'p A':[0,0,0,0,0,0,1],'p B':[0,0,0,0,0,0,0],'p C':[0,0,1,0,0,0,0],'p D':[0,0,0,0,0,0,0],'p E':[0,0,0,0,0,0,0],'p F':[0,0,0,0,0,0,0],'a A':[0,1,0,0,0,0,0],'a B':[0,0,1,0,0,0,0],'a C':[0,0,0,1,0,0,0],'a D':[0,0,0,0,1,0,0],'a E':[0,0,0,0,0,1,0],'a F': [0,0,0,1,1,0,0]})

Примечание. Это сильно упрощенная версия моих фактических данных.

а означает фактическое; p означает предсказанный; A - F представляют серию меток

Я хочу написать запрос, который для каждой строки в моем кадре данных возвращает True, когда: (все значения строки в "p columns" = 0) и (по крайней мере одно значение строки в "a columns" = 1), т.е. для каждой строки , столбцы p фиксируются на 0 и по крайней мере 1 столбец = 1.

Использование ответов на Pandas Dataframe Найти строки, где все столбцы равны и Сравните два столбца с помощью pandas В настоящее время я достигаю этого, используя & и np.any()

((df.iloc[:,6] == 0) & (df.iloc[:,7] == 0) & (df.iloc[:,8] == 0) & (df.iloc[:,9] == 0) & (df.iloc[:,10] == 0) & (df.iloc[:,11] == 0) & df.iloc[:,0:6].any(axis = 1) )

>>
0    False
1     True
2    False
3     True
4     True
5     True
6    False
dtype: bool

Есть ли более краткий, читаемый способ добиться этого?


person Chuck    schedule 07.03.2017    source источник


Ответы (1)


Вы можете использовать ~ для инвертирования логической маски с iloc для выбора по положению:

print (~df.iloc[:,6:11].any(1) & df.iloc[:,0:6].any(1))
0    False
1     True
2    False
3     True
4     True
5     True
6    False
dtype: bool

Или используйте filter для выбора по именам столбцов. , any для проверки хотя бы одного True или all, чтобы проверить, все ли значения True за строку.

Функция eq предназначена для сравнения с 0.

print (~df.filter(like='p').any(1) & df.filter(like='a').any(1))
0    False
1     True
2    False
3     True
4     True
5     True
6    False
dtype: bool

print (df.filter(like='p').eq(0).all(1) & df.filter(like='a').any(1))
0    False
1     True
2    False
3     True
4     True
5     True
6    False
dtype: bool
person jezrael    schedule 07.03.2017
comment
Какой из них будет самым Pythonic / наиболее часто используемым в Pandas? - person Chuck; 07.03.2017
comment
Это зависит от вас, но я предпочитаю больше filter решений, потому что они более динамичны - если добавить несколько столбцов, решение по-прежнему будет работать идеально. - person jezrael; 07.03.2017
comment
Ок, отлично. Спасибо! - person Chuck; 07.03.2017