如何在Python中将多个32位哈希字符串连接并转换为唯一标识符

2024-10-01 00:31:53 发布

您现在位置:Python中文网/ 问答频道 /正文

我遇到了一个问题,我从API中提取数据集用于报告目的,不幸的是它有:

  1. 没有唯一标识符字段
  2. 构成唯一复合键的四个字段中有三个字段都是32位散列值。 它们不应该是散列值,但开发人员似乎出于某种原因在这个特定的API端点中对它们进行了散列

我正在使用Python 3.7.6和pandas 1.0.3。这些数据最终将存储在SQL Server中

对于我的任务,我需要确保在调用RESTAPI时,我可以检查记录的唯一性,如果数据库中的现有记录已更新,则使用唯一标识符来了解要更新的行

32位哈希值会导致以下问题:

  1. 连接构成有效复合键的3个散列字段(和一个datetime字段)时,生成的字符串太长,无法用作数据库主键

  2. 长度似乎在重载.duplicates()函数(例如,请参见下文)

  3. 我不知道如何将它们“解压”为唯一标识符(例如,整数),用于检查数据库中可能需要更新的现有记录如何将此长值转换为有效的唯一标识符,该标识符对于任何完全相同的字符串哈希值都是相同的?

Pandas包括pd.Factorize,理论上可以用于在新提取的数据中创建唯一标识符,但它与数据库中已有的先前提取的数据不一致,因为它将为相同的哈希生成不同的键。此外,与#2类似,factorize在给定字符串长度的情况下也无法准确工作(见下文)

请查找上面的#2示例,其中pandas.duplicates()失败。我将熊猫中的四个复合密钥散列字符串连接在一起,如下所示:

df['id'] = (df['Question ID'].astype(str)+df['WorkflowInstance ID'].astype('str')+df['Agent ID'].astype('str')+df['Evaluation Start Date'].astype('str')).sort_values()

然后做:

df['id'].duplicated().sum()

我得到19份副本:

Out[252]: 19

以下是那些“重复项”(注意:我已经从输出中删除了数据帧行号):

Out[264]: 

100094146736011ea2dbb-ff69-f5d1-8fa5-0242ac11000311e9e0ef-60e7-a470-9724-0242ac1100052020-01-03 11:00:05+11:00

101580231257511ea533b-5eb8-8bb1-a514-0242ac11000211e9e0ef-5ec7-3570-9724-0242ac1100052020-02-20 04:15:04+11:00

102935022988411ea2dbb-ff69-f5d1-8fa5-0242ac11000311e9e0ef-60e7-a470-9724-0242ac1100052020-01-03 11:00:05+11:00

103643806614811ea5122-ee46-6471-a514-0242ac11000211e9e0ef-62d2-f9b0-9724-0242ac1100052020-02-17 12:15:05+11:00

104448956250611ea1d09-3888-4fb1-ad55-0242ac11000411e9e0ef-6156-6bd0-9724-0242ac1100052019-12-13 05:00:03+11:00

104448956250611ea2dbb-ff69-f5d1-8fa5-0242ac11000311e9e0ef-60e7-a470-9724-0242ac1100052020-01-03 11:00:05+11:00

105036638204211ea2dbb-ff69-f5d1-8fa5-0242ac11000311e9e0ef-60e7-a470-9724-0242ac1100052020-01-03 11:00:05+11:00

105439525877511ea1d09-3888-4fb1-ad55-0242ac11000411e9e0ef-6156-6bd0-9724-0242ac1100052019-12-13 05:00:03+11:00

105439525877511ea3cba-ec08-1e01-b4fb-0242ac11000511e9e0ef-6156-6bd0-9724-0242ac1100052020-01-22 13:00:11+11:00

105753070464411ea1d09-3888-4fb1-ad55-0242ac11000411e9e0ef-6156-6bd0-9724-0242ac1100052019-12-13 05:00:03+11:00

105753070464411ea2dbb-ff69-f5d1-8fa5-0242ac11000311e9e0ef-60e7-a470-9724-0242ac1100052020-01-03 11:00:05+11:00

105929086494811ea2dbb-ff69-f5d1-8fa5-0242ac11000311e9e0ef-60e7-a470-9724-0242ac1100052020-01-03 11:00:05+11:00

105942530227011ea1d09-3888-4fb1-ad55-0242ac11000411e9e0ef-6156-6bd0-9724-0242ac1100052019-12-13 05:00:03+11:00

106416598476711ea533b-5eb8-8bb1-a514-0242ac11000211e9e0ef-5ec7-3570-9724-0242ac1100052020-02-20 04:15:04+11:00

107187437764311ea1d09-3888-4fb1-ad55-0242ac11000411e9e0ef-6156-6bd0-9724-0242ac1100052019-12-13 05:00:03+11:00

108645054061411ea1d09-3888-4fb1-ad55-0242ac11000411e9e0ef-6156-6bd0-9724-0242ac1100052019-12-13 05:00:03+11:00

108669477403111ea1d09-3888-4fb1-ad55-0242ac11000411e9e0ef-6156-6bd0-9724-0242ac1100052019-12-13 05:00:03+11:00

108669477403111ea3cba-ec08-1e01-b4fb-0242ac11000511e9e0ef-6156-6bd0-9724-0242ac1100052020-01-22 13:00:11+11:00

108783533783711ea6ebc-2980-1bb1-be7d-0242ac11000311e9e0ef-5a8e-e2f0-a8b3-0242ac1100032020-03-26 04:15:01+11:00

它们似乎不是重复的。考虑到它们是字符串,我会认为它们不会受到浮点或舍入错误的影响

然而!如果我冲洗并重复,我会得到0个副本(应该是这样的):

df['id'][df['id'].duplicated()].sort_values().duplicated().sum()

Out[257]: 0

是什么导致了这种奇怪的行为

这个解决方法至少让我能够识别记录中的唯一性,但它没有解决上述其他问题


Tags: 数据字符串id数据库df记录标识符str
1条回答
网友
1楼 · 发布于 2024-10-01 00:31:53

我提出的解决方案是维护一个已知散列值的二级映射表和一个关联的整数键。我使用它来创建一个唯一的标识符,并将其存储在目标表中,而不是散列中

虽然我对其他选择感兴趣,但这确实回答了主要问题。希望这对某人有所帮助

此外,pandas.duplicated()问题仍然是个谜

干杯 皮特

相关问题 更多 >