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

时间:2016-08-22 17:05:32

标签: python pandas numpy k-means

我正在为k-means聚类准备一些数据。目前我有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?目前这段代码需要很长时间才能运行。

3 个答案:

答案 0 :(得分:1)

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

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

(您可以放弃Hash列并轻松创建新的ID列。)

答案 1 :(得分:0)

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

答案 2 :(得分:0)

您可以使用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'])