首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >(Pandas)如何基于三列相似的数据创建唯一标识符,而顺序并不重要?

(Pandas)如何基于三列相似的数据创建唯一标识符,而顺序并不重要?
EN

Stack Overflow用户
提问于 2019-06-17 22:44:29
回答 3查看 105关注 0票数 1

(Python/Pandas)我正在对英国房价数据进行一些分析,看看房价是否会对附近学校的质量做出反应。我已经将最近的三所学校的URN (唯一的参考号)与数据中的每个房价transaction.These列URN_1,URN_2,URN_3进行了匹配。

我想在数据上估计一个固定效应模型,其中固定效应是基于最近的三个学校。因此,我希望为每个由三个学校组成的集群创建一个唯一的ID,并且我希望这不受学校.e.g顺序的影响。物业A和物业B应具有相同的ID,尽管学校的顺序不同。

代码语言:javascript
复制
Property    URN_1   URN_2   URN_3
A         100053   100052   100054
B         100052   100054   100053

有人知道如何使用Python创建唯一的集群ids吗?

我尝试使用.groupby()用下面的代码创建ID,但是当学校的顺序不同时,会给出不同的集群ID。

以下是我尝试过的方法:

代码语言:javascript
复制
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。

EN

回答 3

Stack Overflow用户

发布于 2019-06-17 23:02:40

如果你的数据不是太长,这是可行的:

代码语言:javascript
复制
# 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()

输出:

代码语言:javascript
复制
  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)唯一定义的(直到一个排列)。所以我们可以计算这些值并按它们分组:

代码语言:javascript
复制
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()

Performance:第一种方法需要14秒来处理200万行,而第二种方法只需要不到1秒。

票数 1
EN

Stack Overflow用户

发布于 2019-06-17 22:49:32

在组合中唯一的类似字符串的对象上使用factorize。由于顺序并不重要,因此我们首先对其进行排序并将其合并。

代码语言:javascript
复制
df['clusterid'] = pd.factorize(df[['URN_1','URN_2','URN_3']].apply(lambda x: ','.join([str(y) for y in sorted(x)]),1))[0]

输出:

代码语言:javascript
复制
       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
票数 0
EN

Stack Overflow用户

发布于 2019-06-17 23:07:54

您可以使用排序后的3个URN为每个URN创建一个字符串。

然后按这个新变量分组,并使用ngroup(),就像您之前尝试的那样

代码语言:javascript
复制
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

输出:

代码语言:javascript
复制
    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
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/56633655

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档