我試圖找到一個矢量/快/ numpy的友好的方式轉換成在A列下面的值,列B:Python/Numpy - 填補非連續點之間的差距?
ID A B
1 0 0
2 0 0
3 1 0
4 1 1
5 0 1
6 0 1
7 -1 1
8 0 0
9 1 0
10 0 1
11 0 1
12 1 1
13 0 1
14 -1 1
15 0 0
算法定義列「B」將填補之間的所有縫隙1和-1的組的值爲1,跳過每對中的第一行。也就是說,對於ID4-ID7,列B填充了1(給定列A @ ID3中的最初1)。接下來,從ID10-ID14填充1(因爲列A @ ID9 = 1)。
雖然這很容易做for循環,但我想知道是否存在非循環解決方案?一個O(n)的循環基礎的解決方案是如下:
import numpy as np
import pandas as pd
x = np.array([ 0, 0, 1, 1, 0 ,0, -1, 0, 1, 0 , 0, 1, 0, -1, 0])
def make_y(x,showminus=False):
y = x * 0
state = 0 # are we in 1 or 0 or -1
for i,n in enumerate(x):
if n == 1 and n != state:
state = n
if i < len(y)-1:
y[i+1] = state
elif n == -1 and n != state:
y[i] = state
if showminus:
state = -1
else:
state = 0
else:
y[i] = state
return y
y = make_y(x)
print pd.DataFrame([x,y]).T
上述功能得到我的機器上具有以下性能:
%timeit y = make_y(x)
10000 loops, best of 3: 28 µs per loop
我猜一定是有方法,使整個事情速度更快,因爲我最終將需要處理的是1000萬個+元素長數組...
是模式始終如果A是1個,那麼下一行是1時至-1出現在答:這是1和-1標誌着連續的開始和結束1s(但不包括1出現在A中的那一行) – EdChum 2014-09-26 12:33:59
@EdChum--這是正確的。然而,你可能已經注意到'make_y'循環函數中有一個參數也可以跟蹤-1區域。爲了簡化事情(最初),我將這一部分放在了問題的範圍之外。 – bazel 2014-09-26 12:52:28
這是棘手的,我想不出沒有迭代的方法,你可以使用類似'mask = df.loc [(df ['A']。shift()== 1)| (df ['A'] == - 1)]'然後使用'mask.loc [(mask ['A'] == -1)| (mask ['A']。shift(-1)!= -1)]'然後應該顯示開始和結束索引,然後遍歷或拉動索引到成對的列表中,並將其設置爲1. – EdChum 2014-09-26 13:25:34