将 160 位哈希转换为机器学习输入的唯一整数 ID

Convert 160 bit Hash to unique integer ids for machine learning input

我正在为 k 均值聚类准备一些数据。目前我有 160 位哈希格式的 ID(这是比特币地址的格式)。

d = {'Hash' : pd.Series(['1HYKGGzRHDskth2ecKZ2HYvxSvQ1p87m6', '3DndG5HuyP8Ep8p3V1i394AUxG4gtgsvoj', '1HYKGGzRHDskth2ecKZ2HYvxSvQ1p87m6']), 
     'X1' : pd.Series([111, 222, 333]),
     'X2' : pd.Series([111, 222, 333]),
     'X3' : pd.Series([111, 222, 333])
    }

df1 = (pd.DataFrame(d))
print(df1)

                                 Hash   X1   X2   X3
0   1HYKGGzRHDskth2ecKZ2HYvxSvQ1p87m6  111  111  111
1  3DndG5HuyP8Ep8p3V1i394AUxG4gtgsvoj  222  222  222
2   1HYKGGzRHDskth2ecKZ2HYvxSvQ1p87m6  333  333  333

为了将此数据解析为 sklearn.cluster.KMeans¶ 算法,我需要将数据转换为 np.float 或 np.array(我认为)。

因此我想将散列值转换为整数值,保持所有行之间的关系。

这是我的尝试:

#REPLACE HASH WITH INT
look_up = {}
count = 0
for index, row in df1.iterrows():
    count +=1
    if row['Hash'] not in look_up:
        look_up[row['Hash']] = count
    else:
        continue
print(look_up)

{'3DndG5HuyP8Ep8p3V1i394AUxG4gtgsvoj': 2, '1HYKGGzRHDskth2ecKZ2HYvxSvQ1p87m6': 1}

此时我运行遍历每个字典并尝试用新的整数值替换散列值。

for index, row in df1.iterrows():
    for address, id_int in look_up.iteritems():
        if address == row['Hash']:            
            df1.set_value(index, row['Hash'], id_int)
print(df1)

输出:

Hash   X1   X2   X3  \
0   1HYKGGzRHDskth2ecKZ2HYvxSvQ1p87m6  111  111  111   
1  3DndG5HuyP8Ep8p3V1i394AUxG4gtgsvoj  222  222  222   
2   1HYKGGzRHDskth2ecKZ2HYvxSvQ1p87m6  333  333  333   

   1HYKGGzRHDskth2ecKZ2HYvxSvQ1p87m6  3DndG5HuyP8Ep8p3V1i394AUxG4gtgsvoj  
0                                1.0                                 NaN  
1                                NaN                                 2.0  
2                                1.0                                 NaN  

输出没有用整数值替换散列地址。如何获得以下输出:

预期输出:

d = {'ID' : pd.Series([1, 2, 1]), 
     'X1' : pd.Series([111, 222, 333]),
     'X2' : pd.Series([111, 222, 333]),
     'X3' : pd.Series([111, 222, 333])
    }

df3 = (pd.DataFrame(d))
print(df3)

   ID   X1   X2   X3
0   1  111  111  111
1   2  222  222  222
2   1  333  333  333

由于行 02 中的散列相同,因此应使用相同的整数 ID 替换散列。

是否有更有效的方法来生成这些唯一 ID?目前这段代码需要很长时间 运行。

有很多方法。一种方法是使用分类代码,另一种方法是对它们进行排名:

In [16]: df1["via_categ"] = pd.Categorical(df1.Hash).codes + 1

In [17]: df1["via_rank"] = df1["Hash"].rank(method="dense").astype(int)
In [18]: df1
Out[18]: 
                                 Hash   X1   X2   X3  via_categ  via_rank
0   1HYKGGzRHDskth2ecKZ2HYvxSvQ1p87m6  111  111  111          1         1
1  3DndG5HuyP8Ep8p3V1i394AUxG4gtgsvoj  222  222  222          2         2
2   1HYKGGzRHDskth2ecKZ2HYvxSvQ1p87m6  333  333  333          1         1

(您可以删除哈希列并同样轻松地创建一个新的 ID 列。)

s = list(set(df1.Hash))
hash2 = dict(zip(s, range(1, len(s) + 1)))
df1.Hash = df1.Hash.map(hash2)
print(df1)

输出:

   Hash   X1   X2   X3
0     2  111  111  111
1     1  222  222  222
2     2  333  333  333

您可以使用 sklearn.preprocessing.LabelEncoder:

from sklearn import preprocessing

le = preprocessing.LabelEncoder()
le.fit(df1['Hash'])
df1['Hash'] = le.transform(df1['Hash'])

结果输出:

   Hash   X1   X2   X3
0     0  111  111  111
1     1  222  222  222
2     0  333  333  333

此外,请注意,这为您提供了一种使用 inverse_transform:

恢复原始哈希的简单方法
df1['Hash'] = le.inverse_transform(df1['Hash'])