繁体   English   中英

根据列的分数计算与Python的并集和交集

[英]Calculate union and intersection with Python based on score of a column

我需要计算2个不同文件的列中元素的加权得分的并集和交集。

输入文件1和输入文件2相同:3个制表符分隔的列:这是一个示例:

输入1

abc with-1-rosette-n    8.1530
abc with-1-tyre-n   6.3597
abc with-1-weight-n 4.8932

输入2

deg about-article-n 3.2917
deg with-1-tyre-n   3.2773
deg about-bit-n 3.4527

我们要计算ABC的第2列中每个值的得分(在Col3中)的相交之和,其中我们考虑最小值(值)和DEG以及每个得分的并集之和(在Col3中) ABC和DEG的Col2中的值。 因此,基本上,所需的输出如下:

在这种情况下:交点= 3.2773(带1-轮胎-n)和联合= 29.3546。

在这里,我们通过将联合除以交集来获得得分:score(intersection)/ score(union)因此,从此样本数据集中,所需的输出如下

abc deg 0.1165

我一直在努力编写脚本,并遇到了一些问题。 我已经从这里这里这里并入了建议,但无法解决我的问题。

这是我正在使用的代码的功能示例:

def polyCalc(a_dict, b_dict):
    intersect = min(classA & classB)
    union = classA | classB

    score = sum(intersect) / sum(union)
    return score

def calculate_polyCalc(classB_infile, classA_infile, outfile):
    targetContext_polyCalc_A = defaultdict(dict)  # { target_lemma : {feat1 : weights, feat2: weights} ...}
    with open(classA_infile, "rb") as opened_infile_A:
        for line_A in opened_infile_A:
            target_class_A, featureA, weight = line_A.split()
            targetContext_polyCalc_A[target_class_A][featureA] = float(weight)

        targetContext_polyCalc_B = defaultdict(dict)
        with open(classB_infile, "rb") as opened_infile_B:
            for line_B in opened_infile_B:
                target_class_B, featureB, weight = line_B.split()
                targetContext_polyCalc_B[target_class_B][featureB] = float(weight)
                classA = set(targetContext_polyCalc_A[featureA])
                classB = set(targetContext_polyCalc_B[featureB])


            with open(outfile, "wb") as output_file:
                poly = polyCalc(targetContext_polyCalc_A[target_class_A], targetContext_polyCalc_B[target_class_B], score)
                outstring = "\t".join([classA, classB, str(poly)])
                output_file.write(outstring + "\n")

我已经按照文档和各个不同的网站中的所有说明进行操作-上面的代码仍在产生错误。 除了给我有关函数union定义的错误外,我似乎还对如何自己定义字典有疑问。 谁能提供一些有关如何解决此问题以达到我期望的结果的“经验”见解?

先感谢您。

PS BTW这是考虑到python2。*编写的。

我可以通过创建自己的类来解决此问题,该类具有set数据类型的属性,并且还可以保存像dict这样的值。 我在下面称它为setmap (也许已经存在这样的东西?或者您可以像一组set一样使用dict.keys()逃脱?

class setmap(set):
    def __init__(self, val_dict):
        super(self.__class__, self).__init__(val_dict.keys())
        self.val_dict = val_dict

    def __getitem__(self, itm):
        return self.val_dict.get(itm)

    def add(self, key, val):
        super(self.__class__, self).add(key)
        self.val_dict[key] = val 

然后这样的事情会起作用:

In [131]: t = setmap({'a':1, 'b':2, 'c':3})

In [132]: t1 = setmap({'a':3, 'd':8})

In [133]: t.intersection(t1)
Out[133]: set(['a'])

In [134]: {x:(t[x] + t1[x]) for x  in t.intersection(t1)}
Out[134]: {'a': 4}

然后,您的目标只是将数据处理为不同的setmap ,一个用于abc数据,一个用于deg数据,等等。

要获得您提到的其他一些统计信息,可以使用相同类型的dict理解,但要使用set.difference (首先是t.difference(t1)然后是t1.difference(t) ),然后使用intersection将结果相加。 它在某种程度上类似于基于包含/排除原理的问题解决方法。

这是一种轻松的方式,并且我不认为加载大量数据对于性能而言是最好的。 另一种选择是将数据直接加载到Pandas DataFrame对象,然后按数据的中间列进行分组并根据需要进行聚合。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM