2017-04-12 48 views
1

我需要生成一個nX3的零數組,但其中一列的值在每行中錯開(1.0)。在每一行中創建一個具有單個交錯值的數組?

所需的輸出:

n = 10 
array([[ 1., 0., 0.], 
     [ 0., 1., 0.], 
     [ 0., 0., 1.], 
     [ 1., 0., 0.], 
     [ 0., 1., 0.], 
     [ 0., 0., 1.], 
     [ 1., 0., 0.], 
     [ 0., 1., 0.], 
     [ 0., 0., 1.], 
     [ 1., 0., 0.]]) 

我試圖切片,重塑一個數組,但一些行包含全零。

我Attemtp:

n = 10 
verts_color = np.zeros(3 * n) 
verts_color[::4] = 1 
verts_color.reshape((n,3)) 
array([[ 1., 0., 0.], 
     [ 0., 1., 0.], 
     [ 0., 0., 1.], 
     [ 0., 0., 0.], 
     [ 1., 0., 0.], 
     [ 0., 1., 0.], 
     [ 0., 0., 1.], 
     [ 0., 0., 0.], 
     [ 1., 0., 0.], 
     [ 0., 1., 0.]]) 

我無法找到一個例子或找出如何解決這個自己,希望有人在這裏也許能幫助我做到這一點?

回答

1

方法#1

def broadcasting_based(n, m): # n :number of cols, m : number of rows 
    return (np.mod(np.arange(m),n)[:,None] == np.arange(n)).astype(float) 

方法2

def tile_based(n, m): # n :number of cols, m : number of rows 
    M = 1+((m-1)//n) 
    return np.tile(np.eye(n),M).T[:m] 

方法3

def initialization_based(n, m): # n :number of cols, m : number of rows 
    M = 1+((m-1)//n) 
    r = np.arange(n) 
    out = np.zeros((M,n,n)) 
    out[:,r,r] = 1 
    out.shape = (-1,n) 
    return out[:m] 

一個多個初始化基於,較短的一個和利用步長的切 -

def initialization_based_v2(n, m): # n :number of cols, m : number of rows 
    out = np.zeros((m,n)) 
    for i in range(n): 
     out[i::n,i] = 1 
    return out 

樣品試驗 -

In [93]: broadcasting_based(n=3, m = 10) 
Out[93]: 
array([[ 1., 0., 0.], 
     [ 0., 1., 0.], 
     [ 0., 0., 1.], 
     [ 1., 0., 0.], 
     [ 0., 1., 0.], 
     [ 0., 0., 1.], 
     [ 1., 0., 0.], 
     [ 0., 1., 0.], 
     [ 0., 0., 1.], 
     [ 1., 0., 0.]]) 

In [94]: np.allclose(broadcasting_based(3,10), tile_based(3,10)) 
Out[94]: True 

In [95]: np.allclose(broadcasting_based(3,10), initialization_based(3,10)) 
Out[95]: True 

In [162]: np.allclose(broadcasting_based(3,10), initialization_based_v2(3,10)) 
Out[162]: True 

運行測試

其他方法 -

# @kmario23's soln 
def using_concatenate(m, n): 
    return np.concatenate([np.identity(m)]* (n//m + 1), axis=0)[:n, :] 

# @Michael's soln  
def initialization_modassign(m, n): 
    x = np.zeros((n,m)) 
    i = np.arange(n) 
    x[i, i%m] = 1 
    return x 

計時 -

In [188]: %timeit broadcasting_based(3,10000) 
    ...: %timeit tile_based(3,10000) 
    ...: %timeit initialization_based(3,10000) 
    ...: %timeit initialization_based_v2(3,10000) 
    ...: %timeit using_concatenate(3,10000) 
    ...: %timeit initialization_modassign(3,10000) 
    ...: 
1000 loops, best of 3: 225 µs per loop 
10000 loops, best of 3: 40.9 µs per loop 
10000 loops, best of 3: 23.6 µs per loop 
10000 loops, best of 3: 20.7 µs per loop 
1000 loops, best of 3: 480 µs per loop 
10000 loops, best of 3: 177 µs per loop 

In [189]: %timeit broadcasting_based(5,10000) 
    ...: %timeit tile_based(5,10000) 
    ...: %timeit initialization_based(5,10000) 
    ...: %timeit initialization_based_v2(5,10000) 
    ...: %timeit using_concatenate(5,10000) 
    ...: %timeit initialization_modassign(5,10000) 
    ...: 
1000 loops, best of 3: 238 µs per loop 
10000 loops, best of 3: 63.6 µs per loop 
10000 loops, best of 3: 33.3 µs per loop 
10000 loops, best of 3: 33.3 µs per loop 
1000 loops, best of 3: 275 µs per loop 
10000 loops, best of 3: 176 µs per loop 

因此,在性能initialization_based_v2似乎工作得很好。

+0

你的第一篇文章之前,你的編輯似乎當你寫像'(NP線完美運行。 mod(np.arange(n),3)[:,None] == np.arange(3))。astype(int)' – Logic1

+0

@divakar但是,我仍然想知道python for'loop如何實現這樣的競爭表現。 – kmario23

+1

@ kmario23它在'n'上迭代,其中'n'只是'3',與向量化一樣好。 – Divakar

1

這是一個有點古怪,但它的工作原理是實現堆疊,你已經事實(垂直)的身份數組,但你需要調整基於n

n = 10 
np.vstack([np.identity(3)]* (n//3 + 1))[:n, :] 

或者行,如果你可以用np.concatenate要提高性能:

np.concatenate([np.identity(3)]* (n//3 + 1), axis=0)[:n, :] 

對於一般使用情況下&改善性能使用以下內容,其中(n, m)分別是行和列。

np.concatenate([np.identity(m)]* (n//m + 1), axis=0)[:n, :] 

例子:

In [151]: n = 10 

In [152]: np.vstack([np.identity(3)]* (n//3 + 1))[:n, :] 
Out[152]: 
array([[ 1., 0., 0.], 
     [ 0., 1., 0.], 
     [ 0., 0., 1.], 
     [ 1., 0., 0.], 
     [ 0., 1., 0.], 
     [ 0., 0., 1.], 
     [ 1., 0., 0.], 
     [ 0., 1., 0.], 
     [ 0., 0., 1.], 
     [ 1., 0., 0.]]) 


# number of columns 
In [170]: m = 3 

# number of rows 
In [171]: n = 10 

In [172]: np.concatenate([np.identity(m)]* (n//m + 1), axis=0)[:n, :] 
Out[172]: 
array([[ 1., 0., 0.], 
     [ 0., 1., 0.], 
     [ 0., 0., 1.], 
     [ 1., 0., 0.], 
     [ 0., 1., 0.], 
     [ 0., 0., 1.], 
     [ 1., 0., 0.], 
     [ 0., 1., 0.], 
     [ 0., 0., 1.], 
     [ 1., 0., 0.]]) 

性能:

In [176]: def using_concatenate(n, m): 
    ...:  return np.concatenate([np.identity(m)]* (n//m + 1), axis=0)[:n, :] 
    ...: 

In [177]: %timeit using_concatenate(n, m) 
10000 loops, best of 3: 22.8 µs per loop 
1
import numpy as np 
n = 10 
x = np.zeros((n,3)) 
i = np.arange(n) 
x[i, i%3] = 1 
+0

非常好,這個沒有碰到我! – Divakar

+0

謝謝。我不知道性能與其他解決方案相比,但它很短;) – Michael

+1

如果您想查看,請在我的文章中爲所有方法添加計時。 – Divakar

相關問題