如何生成 8 位唯一标识符来替换 python pandas 中的现有标识符

Hiw*_*wot 6 python random pandas

假设我有以下简单的数据框。但实际上,我有数十万行这样的行。

\n

df

\n
ID              Sales\n\xe5\x80\x80\xea\xb5\x96\xea\xb3\xbe\xee\x9c\x9e\xea\x86\xb9\xe8\xad\x8b\xe1\xbf\xbe\xe7\x90\x86     100\n\xe5\x80\x80\xea\xb5\x96\xea\xb3\xbe\xee\x9c\x9e\xea\x86\xb9\xef\x8d\x8a         50\n\xe5\x80\x80\xea\xb5\x96\xea\xb3\xbe\xee\x9c\x9e\xea\x86\xb9\xe8\xad\x8b\xe1\xbf\xbe\xe7\x90\x86     70\n\xea\xb3\xbe\xee\x9c\x9e\xea\x86\xb9\xed\x85\x8a\xe8\xba\xa5\xe3\xab\x86        60\n
Run Code Online (Sandbox Code Playgroud)\n

我的想法是我想用随机生成的 8 位数字替换中文数字,如下所示。

\n
ID              Sales\n13434535        100\n67894335         50\n13434535         70\n10986467         60\n
Run Code Online (Sandbox Code Playgroud)\n

数字是随机生成的,但它们也应该保持唯一性。例如,第 0 行和第 2 行相同,当它被替换为随机唯一 ID 时,它也应该相同。

\n

任何人都可以在Python pandas 中帮忙解决这个问题吗?之前已经完成的任何解决方案也是受欢迎的。

\n

ane*_*oid 11

这里的主要方法是使用Series.map()“ID”来分配新值。

用于将 Series 中的每个值替换为另一个值,该值可能源自函数 adict或 a Series

正是您正在寻找的。

以下是生成新 ID的一些选项:

1.随机生成8位整数,按要求

您可以首先使用数据帧中的每个唯一 ID创建随机生成的 8 位整数的映射。然后使用Series.map()“ID”来分配回新值。我添加了一个while循环来确保生成的 ID 是唯一的。

import random

original_ids = df['ID'].unique()
while True:
    new_ids = {id_: random.randint(10_000_000, 99_999_999) for id_ in original_ids}
    if len(set(new_ids.values())) == len(original_ids):
        # all the generated id's were unique
        break
    # otherwise this will repeat until they are

df['ID'] = df['ID'].map(new_ids)
Run Code Online (Sandbox Code Playgroud)

输出:

         ID  Sales
0  91154173    100
1  27127403     50
2  91154173     70
3  55892778     60
Run Code Online (Sandbox Code Playgroud)

编辑和警告:原始 ID 是汉字,长度已经为 8。汉字肯定超过 10 个,因此如果原始 ID 的组合错误,可能无法为新集合创建足够唯一的 8 位数字 ID 。除非您内存有限,否则我建议使用 16-24 位数字。或者甚至更好...

2.使用UUID。[理想的]

您仍然可以使用 ID 的“整数”版本而不是十六进制。这样做的额外好处是不需要检查唯一性:

         ID  Sales
0  91154173    100
1  27127403     50
2  91154173     70
3  55892778     60
Run Code Online (Sandbox Code Playgroud)

(如果您同意十六进制 ID,请将uuid.uuid4().int上面更改为uuid.uuid4().hex。)

输出:

                                        ID  Sales
0   10302456644733067873760508402841674050    100
1   99013251285361656191123600060539725783     50
2   10302456644733067873760508402841674050     70
3  112767087159616563475161054356643068804     60
Run Code Online (Sandbox Code Playgroud)

2.B. UUID 中的数字较小

如果上面生成的 ID 太长,您可以将其截断,但存在一些小风险。在这里,我仅使用前 16 个十六进制字符并将它们转换为 int。您可以将其放入唯一性循环检查中,如上面选项 1 所做的那样。

import uuid

original_ids = df['ID'].unique()
new_ids = {cid: uuid.uuid4().int for cid in original_ids}
df['ID'] = df['ID'].map(new_ids)
Run Code Online (Sandbox Code Playgroud)

输出:

                     ID  Sales
0  14173925717660158959    100
1  10599965012234224109     50
2  14173925717660158959     70
3  13414338319624454663     60
Run Code Online (Sandbox Code Playgroud)

3. 根据实际值创建映射:

这组选项具有以下优点:

  • 不需要唯一性检查,因为它确定性地基于原始 ID 和
    • 所以原来相同的ID会生成相同的新ID
  • 不需要提前创建地图

3.A. CRC32

(与上面的选项 2.B. 相比,发现不同 ID 发生冲突的概率更高。)

                                        ID  Sales
0   10302456644733067873760508402841674050    100
1   99013251285361656191123600060539725783     50
2   10302456644733067873760508402841674050     70
3  112767087159616563475161054356643068804     60
Run Code Online (Sandbox Code Playgroud)

输出:

           ID  Sales
0  2083453980    100
1  1445801542     50
2  2083453980     70
3   708870156     60
Run Code Online (Sandbox Code Playgroud)

3.B. Python 内置hash()的原始 ID [在这种情况下我的首选方法]

  • 可以一行完成,无需导入
  • 相当安全,不会因不同的 ID 而产生冲突
import uuid

original_ids = df['ID'].unique()
DIGITS = 16  # number of hex digits of the UUID to use
new_ids = {cid: int(uuid.uuid4().hex[:DIGITS], base=16) for cid in original_ids}
df['ID'] = df['ID'].map(new_ids)
Run Code Online (Sandbox Code Playgroud)

输出:

                    ID  Sales
0  4663892623205934004    100
1  1324266143210735079     50
2  4663892623205934004     70
3  6251873913398988390     60
Run Code Online (Sandbox Code Playgroud)

3.C. MD5Sum,或任何来自hashlib

由于 ID 预计会很小(8 个字符),因此即使使用 MD5,冲突的概率也非常低

                     ID  Sales
0  14173925717660158959    100
1  10599965012234224109     50
2  14173925717660158959     70
3  13414338319624454663     60
Run Code Online (Sandbox Code Playgroud)

输出:

                     ID  Sales
0  17469287633857111608    100
1   4297816388092454656     50
2  17469287633857111608     70
3  11434864915351595420     60
Run Code Online (Sandbox Code Playgroud)