矢量化"和"对于熊猫列

时间:2016-01-25 20:13:17

标签: python numpy pandas vectorization

使用像这样的数据

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

现在我只得到一个带有for循环::

的丑陋解决方案
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

我们可以避免这个新的 for 循环。

3 个答案:

答案 0 :(得分:4)

您可以使用np.logical_andnumpy's broadcasting

假设您将xy分别定义为第一列和整个矩阵:

import numpy as np

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

现在,使用广播,找到xy的逻辑,并将其放在and_中:

and_ = np.logical_and(x, y)

最后,查找任何列中的任何行是否为真:

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

答案 1 :(得分: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

答案 2 :(得分: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