[英](pandas)How can I create a unique identifier based on three similar columns of data, where order doesn't matter?
(Python/Pandas)我正在对英国房价数据进行一些分析,研究房价是否对附近学校的质量做出反应。 我已经将最近三所学校的 URN(唯一参考编号)与每个房价交易进行了匹配。这些是数据中的 URN_1、URN_2、URN_3 列。
我想估计数据的固定效应模型,其中固定效应基于最近的三所学校。 因此,我想为三所学校的每个集群创建一个唯一的 ID,并且我希望这不受学校顺序的影响。例如,尽管学校的顺序不同,但物业 A 和物业 B 应该具有相同的 ID。
Property URN_1 URN_2 URN_3
A 100053 100052 100054
B 100052 100054 100053
有谁知道我如何使用 Python 创建唯一的集群 ID?
我已经尝试使用 .groupby() 使用下面的代码创建 ID,但是当学校的顺序不同时,这会给出不同的集群 ID。
这是我尝试过的:
import pandas as pd
URN1=[1,2,3,4,5]
URN2=[5,4,3,2,1]
URN3=[1,2,3,2,1]
lst=['a','b','c','d','e']
df=pd.DataFrame(list(zip(URN1,URN2,URN3)),
columns['URN_1','URN_2','URN_3'],index=lst)
df['clusterid']=df.groupby(['URN_1','URN_2','URN_3']).ngroup()
print(df)
我希望观察 'a' 和 'e' 具有相同的集群 id,但是通过这种方法它们被赋予了不同的 id。
如果您的数据不太长,这会起作用:
# we sort the values of each row
# and turn them to tuples
markers = (df[['URN_1','URN_2','URN_3']]
.apply(lambda x: tuple(sorted(x.values)), axis=1)
)
df['clisterid'] = df.groupby(markers).ngroup()
输出:
Property URN_1 URN_2 URN_3 clisterid
0 A 100053 100052 100054 0
1 B 100052 100054 100053 0
选项 2:由于上述解决方案使用apply
,这在某些情况下可能并不理想。 这是一个数学小技巧:众所周知,一个群(a,b,c)
) 由(a+b+c, a**2+b**2+c**2, abc)
。 所以我们可以计算这些值并按它们分组:
tmp_df = df[['URN_1','URN_2','URN_3']]
s = tmp_df.sum(1) # sums
sq = (tmp_df**2).sum(1) # sum of squares
p = tmp_df.prod(1) # products
# groupby
df['clisterid'] = df.groupby([s,sq,p]).ngroup()
性能:第一种方法处理 200 万行需要 14 秒,而第二种方法需要不到 1 秒。
对组合的唯一类似字符串的对象使用factorize 。 既然顺序无关紧要,我们先排序再组合。
df['clusterid'] = pd.factorize(df[['URN_1','URN_2','URN_3']].apply(lambda x: ','.join([str(y) for y in sorted(x)]),1))[0]
输出:
URN_1 URN_2 URN_3 clusterid clisterid
a 1 5 1 0 0
b 2 4 2 1 1
c 3 3 3 2 2
d 4 2 2 3 1
e 5 1 1 4 0
您可以使用排序的 3 个 URN 为每个创建一个字符串。
然后按这个新变量分组并使用 ngroup() 就像你之前尝试过的那样
df['URN_join'] = df[['URN_1','URN_2','URN_3']].apply(lambda x: '_'.join([str(nb) for nb in sorted(x)]), axis=1)
df['clusterid'] = df.groupby(['URN_join']).ngroup()
df
输出 :
URN_1 URN_2 URN_3 clusterid URN_join
a 1 5 1 0 1_1_5
b 2 4 2 1 2_2_4
c 3 3 3 2 3_3_3
d 4 2 2 1 2_2_4
e 5 1 1 0 1_1_5
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.