Python 基于DataFrame列将数据分组到集群中
我有一个类似于以下内容的数据帧df:Python 基于DataFrame列将数据分组到集群中,python,pandas,dataframe,Python,Pandas,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
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
请注意,由于A中的1与B中的2相关,而A中的2与B中的5相关,因此它们都位于同一集群中。A中的8只与B中的9相关,因此被放在另一个簇中
总而言之,我如何基于成对连接定义集群,其中成对由数据帧中的两列定义?这里是一个开始,我不确定我是否理解分组为集群的标准,但是,您应该能够添加确切的标准:
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
这是一个开始,我不确定我是否理解分组到集群的标准,但是,您应该能够添加确切的标准:
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
您可以将其视为一个集合合并问题(每行描述一个集合),或一个连接组件问题(每行描述两个节点之间的边)。顺便说一句,虽然我已经考虑过提交一份PR,将其添加到实用工具中,但是它没有本机支持 无论如何,您可以做如下操作:
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替换为您想要的任何内容。您可以将其视为一个集合合并问题,每行描述一个集合,或一个连接组件问题,每行描述两个节点之间的边。顺便说一句,虽然我已经考虑过提交一份PR,将其添加到实用工具中,但是它没有本机支持 无论如何,您可以做如下操作:
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,2+2,5表示1,5。此外,我的数据中可能有几百个簇,因此对簇罩的二进制确定是不够的。-好的,如果我理解正确,dataframe是一个表示图中连接的边列表。如果是这样,您可以在图中使用集群:或者集群由两个值之间是否存在成对连接来定义。在我的例子中,1,2+2,5表示1,5。此外,我的数据中可能有几百个簇,因此对簇罩的二进制确定是不够的。-好的,如果我理解正确,dataframe是一个表示图中连接的边列表。如果是这样,您可以在图中使用集群:或者