元组的加入,组排序和采用模式

时间:2018-10-16 16:58:53

标签: python list tuples

我遇到以下问题,因为我无法访问import pandas或除标准库之外的任何内容。

ID-type1的词典:标签。

{'ID1': 'Label1',
 'ID2': 'Label2',
 'ID3': 'Label2',
 'ID3': 'Label3',
 'ID4': 'Label1',
 'ID5': 'Label4'...}

具有ID-type1,ID-type2和Val的三元组列表。每个ID都有数千个唯一值。

[('ID1', 'ID_Type2_1', 0.3695652173913043),
 ('ID1', 'ID_Type2_2', 0.35714285714285715),
 ('ID1', 'ID_Type2_3', 0.4146341463414634),
 ('ID2', 'ID_Type2_1', 0.3125),
 ('ID2', 'ID_Type2_2', 0.4418604651162791),
 ('ID2', 'ID_Type2_3', 0.34285714285714286),
 ('ID3', 'ID_Type2_5', 0.35714285714285715),
 ('ID3', 'ID_Type2_3', 0.3488372093023256),
 ('ID3', 'ID_Type2_2', 0.3958333333333333)...]

如果字典是名称为A的数据框(3列),而列表是名称为B的数据框(2列)。我想做以下伪逻辑。

将标签附加到元组列表。

C = left_join(A, B, on =ID-type1)

然后在Val列中与前m个值相对应的行中为每个ID-type2选择模式(标签),换句话说,按ID-type-2分组,然后仅保留前{基于m列的{1}}(整数)行,然后选择Val列的模式/最常用值。

label

换句话说,所需的输出是具有(ID-type2,Label)的元组列表

编辑:我认为第一步可以用这样的东西完成?但是第二步是具有挑战性的部分

C.groupby(ID_type-2).arrange(Val).select(rank = n()).filter(rank <= m).select(mode(label))

1 个答案:

答案 0 :(得分:1)

我认为您可以使用itertools.groupbystatistics模块来做到这一点。考虑您在问题中发布的以下示例数据:

import itertools
import statistics

d = {'ID1': 'Label1',
     'ID2': 'Label2',
     'ID3': 'Label2',
     'ID3': 'Label3',
     'ID4': 'Label1',
     'ID5': 'Label4'}

tups = [('ID1', 'ID_Type2_1', 0.3695652173913043),
        ('ID1', 'ID_Type2_2', 0.35714285714285715),
        ('ID1', 'ID_Type2_3', 0.4146341463414634),
        ('ID2', 'ID_Type2_1', 0.3125),
        ('ID2', 'ID_Type2_2', 0.4418604651162791),
        ('ID2', 'ID_Type2_3', 0.34285714285714286),
        ('ID3', 'ID_Type2_5', 0.35714285714285715),
        ('ID3', 'ID_Type2_3', 0.3488372093023256),
        ('ID3', 'ID_Type2_2', 0.3958333333333333),
        ('ID2', 'ID_Type2_5', 0.4958333333333333)]

您可以通过简单的列表理解来创建“ join”:

res = [(idt2, idt1, d[idt1], val) for idt1, idt2, val in tups]

现在,您可以使用itertools.groupby创建组。在这里,我将分组结果存储在另一个字典中:

res.sort() # groupby expects the list to be sorted by the grouping key

# group by id type 2 and store those grouped lists sorted in descending order of Val
groups = {k: sorted(list(g), key=lambda x: x[-1], reverse=True) for k, g in itertools.groupby(res, key=lambda x: x[0])}

对于上面的示例数据,组如下所示:

[('ID_Type2_3', 'ID1', 'Label1', 0.4146341463414634), ('ID_Type2_3', 'ID3', 'Label3', 0.3488372093023256), ('ID_Type2_3', 'ID2', 'Label2', 0.34285714285714286)]                   
[('ID_Type2_1', 'ID1', 'Label1', 0.3695652173913043), ('ID_Type2_1', 'ID2', 'Label2', 0.3125)]                                                                                     
[('ID_Type2_2', 'ID2', 'Label2', 0.4418604651162791), ('ID_Type2_2', 'ID3', 'Label3', 0.3958333333333333), ('ID_Type2_2', 'ID1', 'Label1', 0.35714285714285715)]                   
[('ID_Type2_5', 'ID2', 'Label2', 0.4958333333333333), ('ID_Type2_5', 'ID3', 'Label3', 0.35714285714285715)]

现在,您可以使用每个组的简单列表切片(最多m个值)来获得模式:

for k, g in groups.items():
    # label_mode_of_first_m_values_for_this_group = statistics.mode([label for idt2, idt1, label, val in g[:m]])