Редактировать
После небольшого копания / размышления я понял, что был неправ: оказывается, &
- это логический оператор в Пандах.&
реализует попарно логические и между pd.Series
и pd.DataFrame
объекты.К сожалению, &
имеет приоритет оператора, отличный от and
, поэтому вы должны быть осторожны с ним (в этом случае &
имеет более высокий приоритет, чем ==
, >
или <
).Ошибка в коде OP просто сводится к отсутствию круглых скобок в нужных местах.
Таким образом, чтобы получить вид маркировки, после которой первоначально был OP, код будет:
import numpy as np
import pandas as pd
data= [
[191, 289, 300, 190, 287, 267],
[191, 289, 300, 200, 312, 400],
[191, 289, 300, 191, 289, 300],
[191, 289, 300, 200, 287, 400],
]
combined_min = pd.DataFrame(data=data, columns=['A', 'B','C','A-1','B-1','C-1'])
cond = lambda x: [(x['A'] == x['A-1']) & (x['B'] == x['B-1']) & (x['C'] == x['C-1']),
(x['A'] > x['A-1']) & (x['B'] > x['B-1']) & (x['C'] > x['C-1']),
(x['A'] < x['A-1']) & (x['B'] < x['B-1']) & (x['C'] < x['C-1'])]
choices = ['same', 'kj_greater', 'mi_greater']
combined_min['que'] = np.select(cond(combined_min), choices, default=np.nan)
print(combined_min)
Это выводит:
A B C A-1 B-1 C-1 que
0 191 289 300 190 287 267 kj_greater
1 191 289 300 200 312 400 mi_greater
2 191 289 300 191 289 300 same
3 191 289 300 200 287 400 nan
Опционально, cond
можно свести к одной строке:
from functools import reduce
from operator import eq, gt, lt, and_
cond = lambda x: [reduce(and_, (op(x[c], x['{}-1'.format(c)]) for c in 'ABC')) for op in (eq, gt, lt)]
Хотя это несколько снижает читабельность.