簡體   English   中英

將唯一數字映射到列表列中每個唯一字符串的最有效的計算方法

[英]Most computationally efficient way to map a unique number to each unique string in a column of lists

這是此問題的后續措施

如何將唯一數字映射到列表列中的每個唯一字符串

詢問如何將唯一編號映射到包含列表的多個熊貓列中的項目。

當項目數(A列和B列中的項目總數)在4,000萬左右時,給出的解決方案似乎非常慢。 我發現了一些可以更快地為數據集分配唯一編號的方法,可處理約4,000萬個項目,但是對於多列的情況卻沒有,這其中的一個包含一個列表。

這是上面鏈接中的最小示例和解決方案:

設置數據框

df = pd.DataFrame(data={'A': ['2f4', '1k1', 'nmk'], 'B': ['x', 'y', 'z']})
df.at[0, 'B'] = ['jki', 'gg4', 'k6k']
df.at[1, 'B'] = ['2f4', 'gg4', 'g24']
df.at[2, 'B'] = ['1k1', 'g24', '1k1', 'pir']

df

     A                     B
0  2f4       [jki, gg4, k6k]
1  1k1       [2f4, gg4, g24]
2  nmk  [1k1, g24, 1k1, pir]

i, u = pd.factorize([*df.A, *np.concatenate(df.B)])
l = df.B.str.len()[:-1].cumsum()
n = len(df)

df.assign(MappedA=i[:n], MappedB=np.split(i[n:], l))

     A                     B  MappedA       MappedB
0  2f4       [jki, gg4, k6k]        0     [3, 4, 5]
1  1k1       [2f4, gg4, g24]        1     [0, 4, 6]
2  nmk  [1k1, g24, 1k1, pir]        2  [1, 6, 1, 7]

我正在嘗試查看是否有更有效的計算解決方案。 我懷疑是這樣,因為有些方法可以在幾分鍾內為4000萬個項目分配唯一的編號(而上述解決方案似乎從未完成)。

這是一個這樣的解決方案

mapping = {k: v for v, k in enumerate(df.A.unique())}  
df['MappedA'] = df.A.map(mapping)

我想知道是否有一種方法可以將其應用於我的情況,其中將A列和B列中的項映射到唯一的數字,從0開始,A列中的項獲得第一個數字,然后分配剩余的唯一項在B列中。

編輯:

一位用戶提到,熊貓不是處理字符串列表的最有效的計算方法。 我可以通過以下方式將其轉換為numpy數組

numpyArray = df.values

因此,如果有一種使用numpy數組解決方案的方法,則可以很容易地實現它。

效率低下是由於我在構造各個部分時所采取的自由度。 我可以通過一些調整來提高性能

a = df.A.values
b = np.concatenate(df.B.values)
i, u = pd.factorize(np.append(a, b))
l = np.array([*map(len, df.B)])[:-1].cumsum()
n = len(df)

df.assign(MappedA=i[:n], MappedB=np.split(i[n:], l))

對於更大的df

df = pd.concat([df] * 10000, ignore_index=True)

%%timeit
i, u = pd.factorize([*df.A, *np.concatenate(df.B)])
l = df.B.str.len()[:-1].cumsum()
n = len(df)

df.assign(MappedA=i[:n], MappedB=np.split(i[n:], l))

# 1 loop, best of 3: 506 ms per loop

%%timeit
a = df.A.values
b = np.concatenate(df.B.values)
i, u = pd.factorize(np.append(a, b))
l = np.array([*map(len, df.B)])[:-1].cumsum()
n = len(df)

df.assign(MappedA=i[:n], MappedB=np.split(i[n:], l))

# 10 loops, best of 3: 95.1 ms per loop

這使我們提高了5倍。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

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