Помещение нескольких условий с помощью np.where на пандах Python? - PullRequest
0 голосов
/ 12 сентября 2018

У меня есть следующий фрейм данных:

load = pd.DataFrame({'A':list('abcdef'),
                   'B':[4,5,4,5,5,4],
                   'C':[7,8,9,4,2,0],
                   'D':[1,3,5,4,2,0],
                   'E':[5,3,6,9,2,4],
                   'F':list('aaabbb')})

Мне нужно проверить b>c, где c=d и оба c,d!=0, если условие удовлетворяет, мне нужно поставить True иначе False.

выход

False
False
False
True
True
False

Ответы [ 3 ]

0 голосов
/ 12 сентября 2018

Я думаю, что нужна логическая цепочка & для bitwise AND:

m = load.B.gt(load.C) & load.C.eq(load.D) & load[['C','D']].ne(0).any(axis=1)
#alternative
m = load.B.gt(load.C) & load.C.eq(load.D) & load['C'].ne(0) & load['D'].ne(0)

print (m)
0    False
1    False
2    False
3     True
4     True
5    False
dtype: bool

Если хотите numpy.where получить тот же вывод:

load['new'] = np.where(m, True, False)
print (load)
   A  B  C  D  E  F    new
0  a  4  7  1  5  a  False
1  b  5  8  3  3  a  False
2  c  4  9  5  6  a  False
3  d  5  4  4  9  b   True
4  e  5  2  2  2  b   True
5  f  4  0  0  4  b  False

Используется, если необходимо установить 2 значения по условию, например:

load['new'] = np.where(m, 10, 20)
print (load)
   A  B  C  D  E  F  new
0  a  4  7  1  5  a   20
1  b  5  8  3  3  a   20
2  c  4  9  5  6  a   20
3  d  5  4  4  9  b   10
4  e  5  2  2  2  b   10
5  f  4  0  0  4  b   20

Производительность

load = pd.concat([load] * 1000, ignore_index=True)

In [106]: %timeit load['print'] = load.apply(lambda x:(x.B>x.C)&(x.C==x.D)&(x.C!=0)&(x.D!=0),axis=1)
408 ms ± 13.3 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)

In [107]: %timeit load['print'] = load.B.gt(load.C) & load.C.eq(load.D) & load['C'].ne(0) & load['D'].ne(0)
1.64 ms ± 135 µs per loop (mean ± std. dev. of 7 runs, 1000 loops each)
0 голосов
/ 12 сентября 2018

Вы можете использовать np.logical_and.reduce с кортежем логических рядов:

m1 = load['B'] > load['C']
m2 = load['C'] == load['D']
m3 = load['C'] != 0
m4 = load['D'] != 0

res = load[np.logical_and.reduce((m1, m2, m3, m4))]

print(res)

   A  B  C  D  E  F
3  d  5  4  4  9  b
4  e  5  2  2  2  b
0 голосов
/ 12 сентября 2018

Попробуйте:

load['print'] = load.apply(lambda x:(x.B>x.C)&(x.C==x.D)&(x.C!=0)&(x.D!=0),axis=1)
   A  B  C  D  E  F  print
0  a  4  7  1  5  a  False
1  b  5  8  3  3  a  False
2  c  4  9  5  6  a  False
3  d  5  4  4  9  b   True
4  e  5  2  2  2  b   True
5  f  4  0  0  4  b  False

или

load['print'] = np.where((load.B>load.C)&(load.C==load.D)&(load.C!=0)&(load.D!=0),True, False)
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...