簡體   English   中英

python從整數列表中為每個'x'元素提取一個熱編碼序列(滑動窗口)

[英]python from a list of integers extract a one-hot encoded sequence for every 'x' elements (sliding window)

我有一個從數據框中獲取的數字列表:

import pandas as pd
import numpy as np

file=pd.read_csv('chr1.bed', sep='\t',header=None)
file.head()
0       chr1    3037109    3037259
1       chr1    3037323    3037473
2       chr1    3037534    3037684
3       chr1    3037771    3037921
4       chr1    3038073    3038223

centers=(file[2]-file[1])/2+file[1]
centers=centers.apply(lambda x: round(x))

因此,“中心”的數組是第二列與第三列之間的差。 我想將此序列轉換為二進制序列,如下所示:

start=file.iloc[0][1]
last=file.shape[0]
end=file.iloc[last-1][2]
values=np.zeros(end-start)
for i in centers:
        values[int(i-start+1)]=1

也就是說,該序列必須是一個零數組,從數據幀第二列的第一個值到第三列的最后一個值開始。 然后使用“中心”數組作為索引,將序列中的中心位置標記為1。

該操作很好,但是現在我有一個問題,我想在大小為100的滑動窗口中執行此操作,從序列中取出10000個塊。 最初,我嘗試通過采用“值”數組並以100的步長移動它並采用下一個10000值來做到這一點:

df=pd.DataFrame.transpose(pd.DataFrame(values[0:10000]))

for i in xrange(100,len(values)-10000,100):
        print(float(i)/float(len(values))) # time assessment
        df=df.append(pd.DataFrame.transpose(pd.DataFrame(values[i:i+10000])))

with open('test.csv', 'w') as f:
        df.to_csv(f, header=False)

根據我習慣評估的行數,這需要4天后才能完成。...必須有一種更快的方法。

總的來說,我的問題是能否將Windows中不規則放置的整數的長序列轉換為Windows中一系列單編碼的矢量?

這是一種無需使用for循環即可完成所需操作的方法(與使用numpy語法相比,這通常會慢得多)

僅僅為了記錄“將不規則放置的整數的長序列轉換為一系列連續的二進制數”被稱為“ one-hot”編碼,在這里就像寫values[centers-start+1]=1一樣容易。 現在,對於第二部分,想法是將n個值的序列循環到n + 1列的數組中,以便獲得所需的滾動窗口效果。

不過要注意的是,此方法正在構建幾個相當大的數組(接近於初始序列長度的平方 ),因此您可能必須將序列拆分為塊(10000序列在我的8GB RAM上工作正常,但30000也是這樣) )和/或使代碼的存儲效率更高。

import numpy as np
import pandas as pd

#example values to have an MCVE
centers =  np.array([5,6,10])
start=5
end=15
values=np.zeros(end-start)

#no need for a loop, we can use an array of indexes to assign the values
values[centers-start+1]=1

print("starting values:",values)

#here I'm choosing the window size
window_size = 4

#we start by duplicating the sequence using broadcasting with an array filled of ones 
broadcasted_arr = np.ones(values.shape[0]-window_size+2)[:,None]*values[None,:]
looped_values = broadcasted_arr.ravel()

#raveled array containing the whole sequence repeating the appropiate number of times to fill our final array
print("looped values :",looped_values)

#to create our rolling window trick we fill an array with one extra column
#that way each line will "eat" a value of the sequence shifting the rest by one column

#to be able to reshape to the desired shape we need to keep the exact number of values to fill the array
size = values.shape[0]+1
cropped_looped_values = looped_values[:size*int(looped_values.shape[0]/size)]
#here's where the aforementioned trick happens
rolling_array = cropped_looped_values.reshape(-1,values.shape[0]+1)
#finaly we crop the result to discard the part of the array that isn't relevant
result = rolling_array[:,:window_size]

print("final result :",result)

這是輸出:

starting values: 
[ 0.  1.  1.  0.  0.  0.  1.  0.  0.  0.]
looped values : 
[ 0.  1.  1.  0.  0.  0.  1.  0.  0.  0.  0.  1.  1.  0.  0.  0.  1.  0.
  0.  0.  0.  1.  1.  0.  0.  0.  1.  0.  0.  0.  0.  1.  1.  0.  0.  0.
  1.  0.  0.  0.  0.  1.  1.  0.  0.  0.  1.  0.  0.  0.  0.  1.  1.  0.
  0.  0.  1.  0.  0.  0.  0.  1.  1.  0.  0.  0.  1.  0.  0.  0.  0.  1.
  1.  0.  0.  0.  1.  0.  0.  0.]
final result : 
[[ 0.  1.  1.  0.]
 [ 1.  1.  0.  0.]
 [ 1.  0.  0.  0.]
 [ 0.  0.  0.  1.]
 [ 0.  0.  1.  0.]
 [ 0.  1.  0.  0.]
 [ 1.  0.  0.  0.]]

暫無
暫無

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

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