我有一个类似于以下内容的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中的两列定义?
答案 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