基于DataFrame列将数据分组到群集中

时间:2015-07-21 18:38:53

标签: python pandas dataframe

我有一个类似于以下内容的DataFrame(df):

A    B   
1    2
1    3
1    4
2    5
4    6
4    7
8    9
9    8

我想添加一个基本上根据A列和B列中的值确定相关群集的列:

A    B    C   
1    2    a
1    3    a
1    4    a
2    5    a
3    1    a
3    2    a
4    6    a
4    7    a
8    9    b
9    8    b

注意,由于1(在A中)与2(在B中)相关,而2(在A中)与5(在B中)有关,因此它们都放在同一个簇中。 8(在A中)仅与9(在B中)相关,因此被放置在另一个群集中。

总而言之,如何根据成对连接定义集群,其中对由DataFrame中的两列定义?

2 个答案:

答案 0 :(得分:3)

您可以将此视为集合合并问题(每行描述一个集合)或连接组件问题(每行描述两个节点之间的边缘)。虽然我已经考虑过将PR添加到实用工具中,但是AFAIK没有原生支持。

无论如何,你可以这样做:

def consolidate(sets):
    # http://rosettacode.org/wiki/Set_consolidation#Python:_Iterative
    setlist = [s for s in sets if s]
    for i, s1 in enumerate(setlist):
        if s1:
            for s2 in setlist[i+1:]:
                intersection = s1.intersection(s2)
                if intersection:
                    s2.update(s1)
                    s1.clear()
                    s1 = s2
    return [s for s in setlist if s]

def group_ids(pairs):
    groups = consolidate(map(set, pairs))
    d = {}
    for i, group in enumerate(sorted(groups)):
        for elem in group:
            d[elem] = i
    return d

之后我们

>>> df["C"] = df["A"].replace(group_ids(zip(df.A, df.B)))
>>> df
   A  B  C
0  1  2  0
1  1  3  0
2  1  4  0
3  2  5  0
4  4  6  0
5  4  7  0
6  8  9  1
7  9  8  1

你可以用你想要的任何东西替换0和1。

答案 1 :(得分:0)

这是一个开始(我不确定我是否理解分组到群集的标准,但是,您应该能够添加准确的标准):

import pandas as pd

x = pd.DataFrame({'A': [1,1,1,2,4,4,8,9],
              'B': [2,3,4,5,6,7,9,8]})

## calculate difference between a and be columns
## (substitute any distance/association function)
x['Diff'] = abs(x['A'] - x['B'])

## assign whether row is in a cluster or not.
x['Incluster'] = x['Diff'] <= 1