2016-08-22 46 views
0

我正在準備一些用於k均值聚類的數據。目前我有160位散列格式的ID(這是比特幣地址的格式)。將160位哈希轉換爲用於機器學習輸入的唯一整數ids

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?此時此代碼需要很長時間才能運行。

回答

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']) 
+0

是有可能預處理k-means的數據,其中一列是列表?該行看起來像這樣:'0 111 [5,6] 222 333' – user3939059

+0

我不這麼認爲。您可能想要將列表元素分成不同的行,即http:// stackoverflow。com/questions/38428796/how-to-do-lateral-view-explode-in-pandas – root

+0

是否意味着首先將所有行轉換爲列?目前每個數據記錄都是由一行 – user3939059

1

有很多方法。一種方法是使用範疇碼,而另一個將是對他們進行排名:(你可能已經放棄了哈希列,並創建了一個新的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 

+0

謝謝你的快速反應 – user3939059

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