簡短的回答
看到最後的快速,但複雜的功能。
發展
遍歷所有trace
是好的,但我不知道它是比大熊貓更好的解決方案。兩者都涉及迭代 - 對角線或列。從概念上講,它更簡單或更清潔,但我不確定速度,特別是在大型陣列上。
每個對角線有不同的長度,[[12],[9,13],...]
。這是一個大紅旗,警告我們,如果不是不可能的話,塊陣列操作是困難的。
隨着scipy.sparse
我可以構造的2D陣列,可以被求和以得到這些痕跡:
In [295]: from scipy import sparse
In [296]: xs=sparse.dia_matrix(x)
In [297]: xs.data
Out[297]:
array([[12, 0, 0],
[ 9, 13, 0],
[ 6, 10, 14],
[ 3, 7, 11],
[ 0, 4, 8],
[ 0, 1, 5],
[ 0, 0, 2]])
In [298]: np.sum(xs.data,axis=1)
Out[298]: array([12, 22, 30, 21, 12, 6, 2])
此稀疏格式在一個二維數組存儲其data
,以及必要的偏移。其實你pd.concat
產生類似的東西:
data[row_indices, col_indices] = x.ravel()
類似:
In [344]: i=[4,5,6,3,4,5,2,3,4,1,2,3,0,1,2]
In [345]: j=[0,1,2,0,1,2,0,1,2,0,1,2,0,1,2]
In [346]: z=np.zeros((7,3),int)
In [347]: z[i,j]=x.ravel()[:len(i)]
In [348]: z
Out[348]:
array([[12, 0, 0],
[ 9, 13, 0],
[ 6, 10, 14],
[ 3, 7, 11],
[ 0, 4, 8],
[ 0, 1, 5],
[ 0, 0, 2]])
In [304]: pd.concat([rectdf.iloc[:, i].shift(-i) for i in range(rectdf.shape[1])], axis=1)
Out[304]:
0 1 2
0 0 4 8
1 3 7 11
2 6 10 14
3 9 13 NaN
4 12 NaN NaN
它看起來像sparse
通過與np.zeros
開始,並以適當的索引填充它創建了一個data
陣列
雖然我仍然需要創建任何形狀的i,j
的方式。對於j
很容易:
j=np.tile(np.arange(3),5)
j=np.tile(np.arange(x.shape[1]),x.shape[0])
重塑i
In [363]: np.array(i).reshape(-1,3)
Out[363]:
array([[4, 5, 6],
[3, 4, 5],
[2, 3, 4],
[1, 2, 3],
[0, 1, 2]])
使我與重新創建:
In [371]: ii=(np.arange(3)+np.arange(5)[::-1,None]).ravel()
In [372]: ii
Out[372]: array([4, 5, 6, 3, 4, 5, 2, 3, 4, 1, 2, 3, 0, 1, 2])
所以綜合起來:
def all_traces(x):
jj = np.tile(np.arange(x.shape[1]),x.shape[0])
ii = (np.arange(x.shape[1])+np.arange(x.shape[0])[::-1,None]).ravel()
z = np.zeros(((x.shape[0]+x.shape[1]-1),x.shape[1]),int)
z[ii,jj] = x.ravel()
return z.sum(axis=1)
它需要更多的測試各種形狀。
此函數比迭代過跡線更快,即使有這樣的小尺寸陣列:
In [387]: timeit all_traces(x)
10000 loops, best of 3: 70.5 µs per loop
In [388]: timeit [np.trace(x,i) for i in range(-(x.shape[0]-1),x.shape[1])]
10000 loops, best of 3: 106 µs per loop
相關:http://stackoverflow.com/q/10792897和http://stackoverflow.com/q/28917414 –