通过数据特征是否相交对数据进行分组

时间:2018-10-22 21:39:47

标签: python pandas dataframe data-structures group-by

假设我们有一张桌子:

id  | aliases
-------------
0   | ['a0', 'a1', 'a4', 'a11']
1   | ['a3', 'a5']
2   | ['a16', 'a18']
3   | ['a6', 'a8', 'a10']
4   | ['a7', 'a8', 'a9']
5   | ['a3', 'a12', 'a14']
6   | ['a5', 'a16', 'a17']

,我想将所有映射到同一个id的{​​{1}}分组在一起;换句话说,最终结果将所有aliases相交的id交叉在一起,以递归方式应用。在上述情况下,我们将:

  • aliases映射到0
  • ['a0', 'a1', 'a4', 'a11']125映射到6
  • ['a3', 'a5', 'a12', 'a14', 'a16', 'a17', 'a18']3映射到4

是否有一种有效的方法来做到这一点?在我的实际用例中,我大约有1500万行。

有一种幼稚的方法,流传输行并检查到目前为止,每个新行中['a6', 'a7', 'a8', 'a9', 'a10']的每个元素是否都在aliases中处理过;如果是这样,则将所有具有匹配的aliases的行收集在一起id,并将它们映射到匹配的aliases的并集。

但是,这种方法在计算上似乎不切实际。

1 个答案:

答案 0 :(得分:0)

要在此表上运行O(n*len(groupcount)复杂性代码并不难,只是让我无所适从:

假设您将id作为ID的列表,将aliases作为ID的列表,则可以执行以下操作:

bins = []
sets = []
for i in id: # Assume from (0 - n)
    alias = aliases[i]
    in_set = False
    for j in range(len(sets)):
        if len(sets[j].intersection(set(alias))) > 0:
            sets[j].update(set(alias)) # add alias to set, if any difference
            in_set = True
            bins[j].append(i) # append id to bins
            break
    if not in_set:
        bins.append([i])
        sets.append(set(alias))

bins将包含id组,并且sets中的相应元素将包含alias组,您可以使用list()将这些组转换回到list。并且由于所有设置操作都是基于哈希的,因此可以确保您的程序在O(n*groupcount)时间内运行。