python 从整数列表中为每个 'x' 元素提取一个单热编码序列(滑动 window)
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))
因此'centers'的数组就是第二列和第三列的差值。
我想将这个序列转换成二进制序列如下:
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
即该序列必须是一个零数组,从数据帧第二列中的第一个值开始到第三列中的最后一个值。然后以'centers'数组为索引,将序列中的中心位置标记为1。
这个操作很好,但是我现在遇到了一个问题,我想在大小为 100 的滑动 window 中执行这个操作,从序列中取出 10000 个块。最初我尝试通过获取 'values' 数组并以 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 中的单热编码向量?
这是一种无需使用 for 循环即可完成所需操作的方法(这往往比使用 numpy 语法慢得多)
记一下"convert a long sequence of unevenly placed integers into a series of continuous binary"就叫"one-hot"编码,这里写values[centers-start+1]=1
就简单了。
现在对于第二部分,想法是将 n 值序列循环到 n+1 列的数组中,以便获得滚动 window 效果。
但请注意,此方法正在构建几个相当大的数组(接近初始序列长度 平方),因此您可能必须将序列分成块(一个序列10000 的内存在我的 8GB RAM 上工作得很好,但 30000 太多了)and/or 使代码的内存效率更高一些。
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.]]
我有一个从数据框中获取的数字列表:
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))
因此'centers'的数组就是第二列和第三列的差值。 我想将这个序列转换成二进制序列如下:
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
即该序列必须是一个零数组,从数据帧第二列中的第一个值开始到第三列中的最后一个值。然后以'centers'数组为索引,将序列中的中心位置标记为1。
这个操作很好,但是我现在遇到了一个问题,我想在大小为 100 的滑动 window 中执行这个操作,从序列中取出 10000 个块。最初我尝试通过获取 'values' 数组并以 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 中的单热编码向量?
这是一种无需使用 for 循环即可完成所需操作的方法(这往往比使用 numpy 语法慢得多)
记一下"convert a long sequence of unevenly placed integers into a series of continuous binary"就叫"one-hot"编码,这里写values[centers-start+1]=1
就简单了。
现在对于第二部分,想法是将 n 值序列循环到 n+1 列的数组中,以便获得滚动 window 效果。
但请注意,此方法正在构建几个相当大的数组(接近初始序列长度 平方),因此您可能必须将序列分成块(一个序列10000 的内存在我的 8GB RAM 上工作得很好,但 30000 太多了)and/or 使代码的内存效率更高一些。
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.]]