簡體   English   中英

熊貓中二進制數據序列的條件長度

[英]Conditional length of a binary data series in Pandas

具有帶有以下列的DataFrame:

df['A'] = [1,1,1,0,1,1,1,1,0,1]

通過某個極限值控制“ 1”系列長度的最佳矢量化方法是什么? 假設限制為2,則結果列“ B”必須看起來像:

   A  B
0  1  1
1  1  1
2  1  0
3  0  0
4  1  1
5  1  1
6  1  0
7  1  0
8  0  0
9  1  1

一種完全矢量化的解決方案是使用shift - groupby - cumsum - cumcount組合1來指示連續cumcount短於2的位置(或您喜歡的任何限制值)。 然后, &這種新的布爾系列與原列:

df['B'] = ((df.groupby((df.A != df.A.shift()).cumsum()).cumcount() <= 1) & df.A)\
          .astype(int) # cast the boolean Series back to integers

這將在DataFrame中產生新列:

   A  B
0  1  1
1  1  1
2  1  0
3  0  0
4  1  1
5  1  1
6  1  0
7  1  0
8  0  0
9  1  1

1參見《 熊貓食譜》 關於分組的部分,“像Python的itertools.groupby一樣進行分組”

另一種方法(檢查前兩個是否為1):

In [443]: df = pd.DataFrame({'A': [1,1,1,0,1,1,1,1,0,1]})

In [444]: limit = 2

In [445]: df['B'] = map(lambda x: df['A'][x] if x < limit else int(not all(y == 1 for y in df['A'][x - limit:x])), range(len(df)))

In [446]: df
Out[446]: 
   A  B
0  1  1
1  1  1
2  1  0
3  0  0
4  1  1
5  1  1
6  1  0
7  1  0
8  0  0
9  1  1

如果您知道該系列中的值都為01 ,那么我想您可以使用涉及卷積的小技巧。 復制列(不必是Pandas對象,它可以只是普通的Numpy數組)

a = df['A'].as_matrix()

並將其與比所需cutoff長度長一的1序列進行卷積,然后切掉最后一個cutoff元素。 例如, cutoff值為2,您會這樣做

long_run_count = numpy.convolve(a, [1, 1, 1])[:-2]

在這種情況下,所得數組給出在該元素之前(包括該元素)的3個元素中出現的1的數目。 如果該數字為3,則說明您正在運行的長度超過了2。因此,只需將這些元素設置為零即可。

a[long_run_count > 2] = 0

現在,您可以將結果數組分配給DataFrame的新列。

df['B'] = a

要將其轉換為更通用的方法:

def trim_runs(array, cutoff):
    a = numpy.asarray(array)
    a[numpy.convolve(a, numpy.ones(cutoff + 1))[:-cutoff] > cutoff] = 0
    return a

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM