Pandas DataFrame выбирает строки на основе значений нескольких столбцов, имена которых указаны в списке - PullRequest
0 голосов
/ 22 января 2019

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

import pandas as pd
import numpy as np
ds = pd.DataFrame({'z':np.random.binomial(n=1,p=0.5,size=10), 
                   'x':np.random.binomial(n=1,p=0.5,size=10), 
                   'u':np.random.binomial(n=1,p=0.5,size=10), 
                   'y':np.random.binomial(n=1,p=0.5,size=10)})
ds
    z   x   u   y
0   0   1   0   0
1   0   1   1   1
2   1   1   1   1
3   0   0   1   1
4   0   0   1   1
5   0   0   0   0
6   1   0   1   1
7   0   1   1   1
8   1   1   0   0
9   0   1   1   1

Как выбрать строки со значениями (0,1) для имен переменных, указанных в списке?

Это то, что я имею до сих пор:

zs = ['z','x']
tf = ds[ds[zs].values == (0,1)]
tf

Теперь напечатано:

    z   x   u   y
0   0   1   0   0
0   0   1   0   0
1   0   1   1   1
1   0   1   1   1
2   1   1   1   1
3   0   0   1   1
4   0   0   1   1
5   0   0   0   0
7   0   1   1   1
7   0   1   1   1
8   1   1   0   0
9   0   1   1   1
9   0   1   1   1

Который показывает дубликаты, а также имеет неправильную строку (строка № 2 - 1,1,1,1). Есть мысли или идеи? Конечно, я предполагаю, что есть питонский способ сделать это без вложенных циклов и грубой форсировки.

Ответы [ 4 ]

0 голосов
/ 22 января 2019

Более простой способ - использовать логическое индексирование :

f = ds['z'] == 0
g = ds['x'] == 1
ds[f & g]
0 голосов
/ 22 января 2019

Вы можете использовать широковещательное сравнение NumPy:

df[(df[['z','x']].values == [0, 1]).all(1)]

   z  x  u  y
0  0  1  0  0
1  0  1  1  1
7  0  1  1  1
9  0  1  1  1

Вы также можете использовать np.logical_and.reduce:

cols = ['z', 'x']
vals = [0, 1]

df[np.logical_and.reduce([df[c] == v for c, v in zip(cols, vals)])]

   z  x  u  y
0  0  1  0  0
1  0  1  1  1
7  0  1  1  1
9  0  1  1  1

Наконец, предполагая, что имена ваших столбцов совместимы, динамически генерировать строки выражения запроса для использования с query:

querystr = ' and '.join([f'{c} == {v!r}' for c,  v in zip(cols, vals)])
df.query(querystr)

   z  x  u  y
0  0  1  0  0
1  0  1  1  1
7  0  1  1  1
9  0  1  1  1

Где {v!r} совпадает с {repr(v)}.

0 голосов
/ 22 января 2019

Использование eq, и очень похоже на метод простуды холодной

df[df[zs].eq(pd.Series([0,1],index=zs),1).all(1)]
   z  x  u  y
0  0  1  0  0
1  0  1  1  1
7  0  1  1  1
9  0  1  1  1
0 голосов
/ 22 января 2019

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

cols = ['u','x']
bools = ds[cols].apply(lambda x: all(x == (0,1)), axis=1)
ds[bools]

   u  x  y  z
0  0  1  1  1
7  0  1  0  1
8  0  1  1  0
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...