用于匹配多列中的值的函数

时间:2016-12-02 23:35:36

标签: python pandas

使用以下测试数据:

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']时创建了显示1值的df2.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,则函数将在[&#39; matches&#39;]列中返回3。

是否有一个功能已经做了类似的事情或任何人可以帮助解决这个问题?

2 个答案:

答案 0 :(得分:2)

您可以为每对列使用阈值,然后将得到的布尔列相加以获得所需的数字。但请注意,此数字取决于比较列的顺序。如果您使用abs(df['A']-df['B'])等,这种模糊性就会消失,这很可能是您的意图。下面我假设这是你需要的。

通常,您可以使用itertools.combinations生成每对列一次:

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()中的生成器表达式遍历每个列对,并构造相应的布尔向量。这些对每个列对求和,并将结果列附加到数据帧。

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')]

但是如果你使用的是绝对值,那么这并不重要(从那时起,差异就相对于列而言是对称的)。

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

如果需要,它可以推广到任意数量的列。