2016-01-25 3 views
5

С данными, как это одинВекторизованных «и» для панд колонн

import pandas as pd 
tcd = pd.DataFrame({ 
'a': {'p_1': 1, 'p_2': 1, 'p_3': 0, 'p_4': 0}, 
'b': {'p_1': 0, 'p_2': 1, 'p_3': 1, 'p_4': 1}, 
'c': {'p_1': 0, 'p_2': 0, 'p_3': 1, 'p_4': 0}}) 
tcd 
#  a b c 
# p_1 1 0 0 
# p_2 1 1 0 
# p_3 0 1 1 
# p_4 0 1 0 

(но с 40e3 колоннами)

Я ищу векторизованный способ поставить логический и в серии результатов :

a & b = ab -> 1 or True a & c = ac -> 0 or False 
1 0 0     1 0 0 
1 1 0     1 0 0 
0 1 1     0 1 0 
0 1 0     0 0 0 

Сейчас я получаю только уродливое решение с петлей для ::

res = pd.Series(index=['a&a', 'a&b', 'a&c']) 
for i in range(3): 
    res[i] = (tcd.iloc[:, 0] & tcd.iloc[:, i]).any() 

res 
aa 1 
ab 1 
ac 0 

с B.M. ответ я получаю это

def get_shared_p(tcd, i): 
    res = (tcd.iloc[:, i][:, None] & tcd).any() 
    res.index += '&_{}'.format(i) 
    return res 

res = pd.DataFrame(columns=range(cols), index=range(cols)) 
for col_i in range(cols): 
    res.iloc[:, col_i] = list(get_shared_p(tcd, col_i)) 

print res 
#  0  1  2 
# 0 True True False 
# 1 True True True 
# 2 False True True 

Мы можем, вероятно, избежать этого нового для цикла.

ответ

3

Использование [:,None] для выравнивания данных и силы вещания:

In[1] : res=(tcd.a[:,None] & tcd).any(); res.index+='&a'; res 

Out[1]: 
a&a  True 
b&a  True 
c&a False 
dtype: bool 
+0

действительно замечательный @ b-m! BTW мы можем использовать тот же метод, чтобы получить кросс-матрицу с & a, & b, & c или с & _0, & _1, & 2 – user3313834

+0

IIUC, 'res = (tcd.T.p_1 [:, None] & tcd.T) .any (); res.index + = '&p_1'; res'? –

+0

B.M. Я обновил вопрос, чтобы объяснить это. – user3313834

4

Вы можете использовать np.logical_and и numpy's broadcasting.

Say вы определяете x и y в качестве первого столбца, и вся матрица, соответственно:

import numpy as np 

x = tcd.as_matrix() 
y = tcd.a.values.reshape((len(tcd), 1)) 

сейчас, используя вещание, найти логическое и x и y, и поместить его в and_:

and_ = np.logical_and(x, y) 

Наконец, найти, если любой из строк в любом из столбцов верно:

>>> np.sum(and_) > 0 
array([ True, True, False], dtype=bool) 
1

Я бы решить эту проблему таким образом:

import pandas as pd 
import numpy as np 
from itertools import combinations 

tcd = pd.DataFrame({ 
'a': {'p_1': 1, 'p_2': 1, 'p_3': 0, 'p_4': 0}, 
'b': {'p_1': 0, 'p_2': 1, 'p_3': 1, 'p_4': 1}, 
'c': {'p_1': 0, 'p_2': 0, 'p_3': 1, 'p_4': 0}}) 

for c in combinations(tcd.columns, 2): 
    tcd[c[0]+c[1]] = np.logical_and(tcd[c[0]], tcd[c[1]]) 

print(cd) 

С выходом:

 a b c  ab  ac  bc 
p_1 1 0 0 False False False 
p_2 1 1 0 True False False 
p_3 0 1 1 False False True 
p_4 0 1 0 False False False 
+0

Я должен сказать, , похоже, что это будет очень медленно. –

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