簡體   English   中英

(pandas)如何根據三個相似的數據列創建唯一標識符,其中順序無關緊要?

[英](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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM