2016-12-02 87 views
2

使用以下试验数据:函数在多个列匹配值

df2 = pd.DataFrame(np.random.randn(12, 3), columns=['A', 'B', 'C']) 
thresh = .3 
df2['matches'] = np.where(df2.A - df2.B < thresh,1,0) 

我创建的df2['matches']柱表示1df2.A - df2.B < thresh的值。

 A   B   C  matches 
0 0.501554 -0.589855 -0.751568 0 
1 -0.295198 0.512442 0.466915 1 
2 0.074863 0.343388 -1.700998 1 
3 0.115432 -0.507847 -0.825545 0 
4 1.013837 -0.007333 -0.292192 0 
5 -0.930738 1.235501 -0.652071 1 
6 -1.026615 1.389294 0.035041 1 
7 0.969147 -0.397276 1.272235 0 
8 0.120461 -0.634686 -1.123046 0 
9 0.956896 -0.345948 -0.620748 0 
10 -0.552476 1.376459 0.447807 1 
11 0.882275 0.490049 0.713033 0 

不过,我其实想比较这三个列,如果值是内thresh它将返回匹配的df2['matches]量相应的数字。因此,例如,如果Col A = 1,B = 2和C = 1.5且thresh为.5,则函数将在['matches']列中返回3。

有没有一个功能已经做了类似的事情或任何人都可以帮助吗?

回答

2

您可以使用每对列的阈值,然后总结得到的布尔列以获得您需要的数字。但请注意,该数字取决于您比较列的顺序。如果你使用了abs(df['A']-df['B'])等,这种含糊不清的情况将会消失,这可能是你的意图。下面我会假设这是你需要的。在每列对

from itertools import combinations 
df = pd.DataFrame(np.random.randn(12, 3), columns=['A', 'B', 'C']) 
thresh = .3 
df['matches'] = sum(abs(df[k1]-df[k2])<thresh for k1,k2 in combinations(df.keys(),2)) 

发电机表达在sum()回路,并构造相应的布尔矢量:

一般来说,可以使用itertools.combinations以产生每对列一次。对每个列对汇总这些值,并将结果列附加到数据帧。

例输出thresh = 0.3

  A   B   C matches 
0 0.146360 -0.099707 0.633632  1 
1 1.462810 -0.186317 -1.411988  0 
2 0.358827 -0.758619 0.038329  0 
3 0.077122 -0.213856 -0.619768  1 
4 0.215555 1.930888 -0.488517  0 
5 -0.946557 -0.904743 -0.004738  1 
6 -0.080209 -0.850830 -0.866865  1 
7 -0.997710 -0.580679 -2.231168  0 
8 1.762313 -0.356464 -1.813028  0 
9 1.151338 0.347636 -1.323791  0 
10 0.248432 1.265484 0.048484  1 
11 0.559934 -0.401059 0.863616  0 

使用itertools.combinations,列相比

>>> [k for k in itertools.combinations(df.keys(),2)] 
('A', 'B'), ('A', 'C'), ('B', 'C')] 

但如果您使用的绝对值(从那以后,真的没关系差异相对于列是对称的)。

+0

谢谢@Andras迪克。也许我的问题有问题,但第10行显示了3个匹配,而1.260968和0.690971之间的差异> thresh。当数字之间的差值 ade1e

+0

@adele查看我的最后一个代码块:我们的顺序是'('B','C')',所以我们计算'B'列减去'C'列,这对这种情况是负的。你可能希望它一路走去,通过交换在列表理解'k1'和'k2'(编辑;现在发电机的表情,里面'总和()');但最可能的情况是你需要差异的绝对值,而不是差异本身。你明白我的意思吗? –

+0

你能告诉我如何得到差异的绝对值,我会看看如果这给出了我期待的结果,谢谢 – ade1e

1

试试这个家伙:

df2['matches'] = df2.apply(lambda x: sum([x[i] - x[j] <= thresh for i, j in [(0, 1), (0, 2), (1, 2)]]), axis=1) 

它必要时可推广到任意数量的列。

-2

这里有一个办法做到这一点:

df2 = pd.DataFrame(np.random.randn(12, 3), columns=['A', 'B', 'C']) 
thresh = 0.3 

newcol = [] 
for row in df2.iterrows(): 
    newcol.append(sum([v > thresh for v in list(row[1])])) 
df2['matches'] = newcol 
+0

“有多少列>门槛”可以用更少的工作负责;这不是问题。 –