2017-08-28 31 views
1

我有一個向量布爾型,維數爲1 * n,假設爲n = 6向量化的方法來將1維布爾數組更改爲2維,python 3

vec = [1, 0, 1, 0, 0, 1] 

我想將其更改爲n * 2矩陣。對於vec中的每個元素,如果它是1,那麼在矩陣中對應的行應該是[1, 0];如果是0,那麼相應的行應該是[0, 1]。因此,所產生的基質應

matr = [[1, 0], 
     [0, 1], 
     [1, 0], 
     [0, 1], 
     [0, 1], 
     [1, 0]] 

要轉換到矩陣向量,我需要一個優雅的量化方法(避免for-loops),因爲在實際情況下n會比6大得多。 此轉換的原因是機器學習分類purppose。 vec指的是binary classification,而matr將用於categorical classification。也許這些信息可以使我的問題更具體。

我使用Python 3,numpy/scipy,sklearn。

任何人都可以幫助我嗎?謝謝。

回答

3

假設vecnumpy.array

vec = np.array([1, 0, 1, 0, 0, 1]) 

然後,可以將其疊逐列與自身按位異或從0-> 1和1-> 0翻轉值,例如:

out = np.stack((vec, vec^1), axis=1) 

爲您提供:

array([[1, 0], 
     [0, 1], 
     [1, 0], 
     [0, 1], 
     [0, 1], 
     [1, 0]]) 

感謝Warren Weckesser爲這表明更快的廣播方式在a comment

vec[:,None]^[0, 1] 

基本時序:

In [33]: %timeit np.stack((a, a^1), axis=1) 
15.6 µs ± 199 ns per loop (mean ± std. dev. of 7 runs, 10000 loops each) 

In [34]: %timeit a[:,None]^[0, 1] 
7.4 µs ± 45.5 ns per loop (mean ± std. dev. of 7 runs, 100000 loops each) 
+0

您可以消除對'stack'需要的東西,如' vec [:,None]^[0,1]'。 –

+0

@沃倫夢幻般的想法......它也來自一個簡單的時間〜約50%的速度 - 你想發佈一個答案嗎? –

+0

@aura我會選擇沃倫的方法。它不一定很明顯,但它要快得多,並能產生你想要的結果。 –

2

下面是與數組索引的一種方法。基本上,我們將使用2D陣列和兩個子陣列,01映射從vec。對於索引部分,np.take對於這樣的重複索引非常有效。實施將是這個樣子 -

mapping = np.array([[0,1],[1,0]]) 
out = np.take(mapping, vec, axis=0) 

採樣運行 -

In [115]: vec = np.array([1, 0, 1, 0, 0, 1]) 

In [116]: np.take(np.array([[0,1],[1,0]]), vec, axis=0) 
Out[116]: 
array([[1, 0], 
     [0, 1], 
     [1, 0], 
     [0, 1], 
     [0, 1], 
     [1, 0]]) 

上更大的數據集運行測試 -

In [108]: vec = np.random.randint(0,2,(10000000)) 

# @Jon Clements's soln 
In [109]: %timeit np.stack((vec, vec^1), axis=1) 
10 loops, best of 3: 50.2 ms per loop 

# @Warren Weckesser's suggestion soln 
In [110]: %timeit vec[:,None]^[0, 1] 
10 loops, best of 3: 90 ms per loop 

# Proposed in this post 
In [111]: %timeit np.take(np.array([[0,1],[1,0]]), vec, axis=0) 
10 loops, best of 3: 31 ms per loop 
+0

好吧...讓我們再試一次...我得到堆棧:2.44ms,廣播:3.12ms,採取:1.06ms所以 - 看起來像進一步改進:) –

+0

@JonClements很好,以獲得確認結果,謝謝! – Divakar