如何编写占 step_size 为 0 的滑动 window 算法?
How to write a sliding window algorithm that accounts for a step_size of 0?
我正在处理一个大型文本文件,其中包含具有这种格式的 pi 的小数位。注意header全是数字,没有字符串。
Header格式:Number_of_sequencesTotal_Pi_DigitsFile_Version_Number
550 10000 5
*Pi Sequence Part 1
1415926535897932384
*Pi Sequence Part 2
6264338327950288419
*Pi Sequence Part 3
1693993751058209749
我需要使用三个参数(window_size、step_size 和 last_windowstart)制作一个滑动 window 来裁剪文件。 last_windowstart 是最后一个 window 开始的地方。
文件数由 Total_Pi_Digits 除以 window 确定。
如果文件有 99 个 Total_Pi_Digits,window_size 个 10,一个 step_size 为零,那么总共有 11 个 windows,因为 99// 10=10 和 99%10 在 window 11 中留下 9。
lastwindow_start 我猜这个例子应该是 90。我不确定我是否需要 last_window 开始。
对于每个 window,将创建一个名为 PiSubsection# 的文件
其中 # 是 window 数字。
对于每个文件,每个 window 都应该有相同的新 header,其中 Number_of_sequences Total_Pi_Digits File_Version_Number 是 header 格式。
Number_of_sequences Total_Pi_Digits 将根据 window_size 和 step_size 更改,但 File_Version_Number 不得更改。
我的问题是我的滑动 window 算法没有考虑到 step_size 0,并且它没有生成正确数量的文件。
到目前为止,它生成的文件数量是原来的两倍,我不确定为什么。
此外,我不确定我是否理解滑动 window 算法中 windows 数量的数学运算。
如何修复我的滑动 window 算法以接受 step_size 0 并生成正确数量的输出文件?
inputFileName = example.txt
import shlex
def sliding_window(windows_size, step_size, lastwindow_start):
for i in xrange(0, lastwindow_start, step_size):
yield (i, i + windows_size)
def PiCrop(windows_size, step_size):
with open(inputFileName, 'r') as input:
first_line = shlex.split(input.readline().strip())
PiNumber = int(first_line[1])
lastwindow_start = PiNumber-(PiNumber%windows_size)
flags = [False for i in range(lastwindow_start)]
first_line[1] = str(windows_size * int(first_line[0]))
first_line = " ".join(first_line)
for line in input:
if line.startswith(first_line[0]):
pass
elif line.startswith('*'):
Indiv = line
else:
for counter, window in enumerate(sliding_window(windows_size,step_size,lastwindow_start)):
newline = line[window[0]:window[1]]
with open('PiSection{}.txt'.format(counter), 'a') as output:
if (flags[counter] == False):
flags[counter] = True
output.write(first_line + '\n')
output.write(Indiv)
output.write(newline + '\n')
下面的示例代码提供了一种替代方法,可以避免进行计算。我认为您加载数字文件或之后实际写入 'window' 文件都没有问题,因此我的代码假定它们已加载并生成一个 windows 数字数组准备写入.
根据该结果,您可以简单地迭代现在派生的 windows 并像以前一样输出文件,或者您可以深入嵌套数据并获取单独的 windows 以根据需要进行处理.
示例输出如下。让我知道是否需要更多详细信息...
import pprint
# Separated just for easy comparison with the output.
pi_digits = '1415926535' + '8979323846' + '2643383279' + '5028841916' + '9399375105' + '8209749'
total_digits = len(pi_digits)
def splitIntoWindows(digits, window_size):
result = []
count = 0
window = -1
for digit in digits:
index = count % window_size
if index == 0:
window += 1
result.append([])
result[window] += digit
count += 1
return result
windows = splitIntoWindows(pi_digits, 10)
print("Split into {} window(s):".format(len(windows)))
pprint.pprint(windows)
示例输出:
Split into 6 window(s):
[['1', '4', '1', '5', '9', '2', '6', '5', '3', '5'],
['8', '9', '7', '9', '3', '2', '3', '8', '4', '6'],
['2', '6', '4', '3', '3', '8', '3', '2', '7', '9'],
['5', '0', '2', '8', '8', '4', '1', '9', '1', '6'],
['9', '3', '9', '9', '3', '7', '5', '1', '0', '5'],
['8', '2', '0', '9', '7', '4', '9']]
编辑
为了避免我做太多假设,这里有一个片段来解析加载的数字文件:
# Assumed these are the contents loaded in:
file_contents = '''
550 10000 5
*Pi Sequence Part 1
1415926535897932384
*Pi Sequence Part 2
6264338327950288419
*Pi Sequence Part 3
1693993751058209749
'''
pi_digits = ''
line_num = 0
for line in file_contents.split('\n'):
line = line.strip()
if (len(line) > 0) & (line[0:1] != "*"):
line_num += 1
if (line_num > 1):
pi_digits += line
这应该让 pi_digits 可以使用,所以你可以用这个代替我上面代码中 pi_digits
的声明。
解决方案是将文件存储在列表中,然后使用该列表的块和滑动 window 生成器来创建所有迷你文件。
inputFileName = "sample.txt"
import itertools
import linecache
def sliding_window(window_size, step_size, lastwindow_start):
for i in xrange(0, lastwindow_start, step_size):
yield (i, i + window_size)
yield (lastwindow_start, total_pi_digits)
def PiCrop(window_size, step_size):
f = open(inputFileName, 'r')
first_line = f.readline().split()
total_pi_digits = int(first_line[0])
lastwindow_start = total_pi_digits-(total_pi_digits%window_size)
lastcounter = (total_pi_digits//window_size)*(window_size/step_size)
flags = [False for i in range(lastcounter)]
first_line[0] = str(window_size)
second_line = f.readline().split()
offset = int(round(float(second_line[0].strip('\n'))))
first_line = " ".join(first_line)
f. close()
with open(inputFileName, 'r') as f:
header = f.readline()
data = [line.strip().split(',') for line in f.readlines()]
for counter, window in enumerate(sliding_window(window_size,step_size,lastwindow_start)):
chunk = data[window[0]:window[1]]
print window
with open('PiCrop_{}.txt'.format(counter), 'w') as output:
if (flags[counter] == False):
flags[counter] = True
headerline = float(linecache.getline(inputFileName, window[1]+1)) - offset
output.write(str(window_size) + " " + str("{0:.4f}".format(headerline)) + " " + 'L' + '\n')
for item in chunk:
newline = str("{0:.4f}".format(float(str(item).translate(None, "[]'"))-offset))
output.write(str(newline) + '\n')
我正在处理一个大型文本文件,其中包含具有这种格式的 pi 的小数位。注意header全是数字,没有字符串。
Header格式:Number_of_sequencesTotal_Pi_DigitsFile_Version_Number
550 10000 5
*Pi Sequence Part 1
1415926535897932384
*Pi Sequence Part 2
6264338327950288419
*Pi Sequence Part 3
1693993751058209749
我需要使用三个参数(window_size、step_size 和 last_windowstart)制作一个滑动 window 来裁剪文件。 last_windowstart 是最后一个 window 开始的地方。
文件数由 Total_Pi_Digits 除以 window 确定。
如果文件有 99 个 Total_Pi_Digits,window_size 个 10,一个 step_size 为零,那么总共有 11 个 windows,因为 99// 10=10 和 99%10 在 window 11 中留下 9。
lastwindow_start 我猜这个例子应该是 90。我不确定我是否需要 last_window 开始。
对于每个 window,将创建一个名为 PiSubsection# 的文件 其中 # 是 window 数字。
对于每个文件,每个 window 都应该有相同的新 header,其中 Number_of_sequences Total_Pi_Digits File_Version_Number 是 header 格式。
Number_of_sequences Total_Pi_Digits 将根据 window_size 和 step_size 更改,但 File_Version_Number 不得更改。
我的问题是我的滑动 window 算法没有考虑到 step_size 0,并且它没有生成正确数量的文件。 到目前为止,它生成的文件数量是原来的两倍,我不确定为什么。
此外,我不确定我是否理解滑动 window 算法中 windows 数量的数学运算。
如何修复我的滑动 window 算法以接受 step_size 0 并生成正确数量的输出文件?
inputFileName = example.txt
import shlex
def sliding_window(windows_size, step_size, lastwindow_start):
for i in xrange(0, lastwindow_start, step_size):
yield (i, i + windows_size)
def PiCrop(windows_size, step_size):
with open(inputFileName, 'r') as input:
first_line = shlex.split(input.readline().strip())
PiNumber = int(first_line[1])
lastwindow_start = PiNumber-(PiNumber%windows_size)
flags = [False for i in range(lastwindow_start)]
first_line[1] = str(windows_size * int(first_line[0]))
first_line = " ".join(first_line)
for line in input:
if line.startswith(first_line[0]):
pass
elif line.startswith('*'):
Indiv = line
else:
for counter, window in enumerate(sliding_window(windows_size,step_size,lastwindow_start)):
newline = line[window[0]:window[1]]
with open('PiSection{}.txt'.format(counter), 'a') as output:
if (flags[counter] == False):
flags[counter] = True
output.write(first_line + '\n')
output.write(Indiv)
output.write(newline + '\n')
下面的示例代码提供了一种替代方法,可以避免进行计算。我认为您加载数字文件或之后实际写入 'window' 文件都没有问题,因此我的代码假定它们已加载并生成一个 windows 数字数组准备写入.
根据该结果,您可以简单地迭代现在派生的 windows 并像以前一样输出文件,或者您可以深入嵌套数据并获取单独的 windows 以根据需要进行处理.
示例输出如下。让我知道是否需要更多详细信息...
import pprint
# Separated just for easy comparison with the output.
pi_digits = '1415926535' + '8979323846' + '2643383279' + '5028841916' + '9399375105' + '8209749'
total_digits = len(pi_digits)
def splitIntoWindows(digits, window_size):
result = []
count = 0
window = -1
for digit in digits:
index = count % window_size
if index == 0:
window += 1
result.append([])
result[window] += digit
count += 1
return result
windows = splitIntoWindows(pi_digits, 10)
print("Split into {} window(s):".format(len(windows)))
pprint.pprint(windows)
示例输出:
Split into 6 window(s):
[['1', '4', '1', '5', '9', '2', '6', '5', '3', '5'],
['8', '9', '7', '9', '3', '2', '3', '8', '4', '6'],
['2', '6', '4', '3', '3', '8', '3', '2', '7', '9'],
['5', '0', '2', '8', '8', '4', '1', '9', '1', '6'],
['9', '3', '9', '9', '3', '7', '5', '1', '0', '5'],
['8', '2', '0', '9', '7', '4', '9']]
编辑
为了避免我做太多假设,这里有一个片段来解析加载的数字文件:
# Assumed these are the contents loaded in:
file_contents = '''
550 10000 5
*Pi Sequence Part 1
1415926535897932384
*Pi Sequence Part 2
6264338327950288419
*Pi Sequence Part 3
1693993751058209749
'''
pi_digits = ''
line_num = 0
for line in file_contents.split('\n'):
line = line.strip()
if (len(line) > 0) & (line[0:1] != "*"):
line_num += 1
if (line_num > 1):
pi_digits += line
这应该让 pi_digits 可以使用,所以你可以用这个代替我上面代码中 pi_digits
的声明。
解决方案是将文件存储在列表中,然后使用该列表的块和滑动 window 生成器来创建所有迷你文件。
inputFileName = "sample.txt"
import itertools
import linecache
def sliding_window(window_size, step_size, lastwindow_start):
for i in xrange(0, lastwindow_start, step_size):
yield (i, i + window_size)
yield (lastwindow_start, total_pi_digits)
def PiCrop(window_size, step_size):
f = open(inputFileName, 'r')
first_line = f.readline().split()
total_pi_digits = int(first_line[0])
lastwindow_start = total_pi_digits-(total_pi_digits%window_size)
lastcounter = (total_pi_digits//window_size)*(window_size/step_size)
flags = [False for i in range(lastcounter)]
first_line[0] = str(window_size)
second_line = f.readline().split()
offset = int(round(float(second_line[0].strip('\n'))))
first_line = " ".join(first_line)
f. close()
with open(inputFileName, 'r') as f:
header = f.readline()
data = [line.strip().split(',') for line in f.readlines()]
for counter, window in enumerate(sliding_window(window_size,step_size,lastwindow_start)):
chunk = data[window[0]:window[1]]
print window
with open('PiCrop_{}.txt'.format(counter), 'w') as output:
if (flags[counter] == False):
flags[counter] = True
headerline = float(linecache.getline(inputFileName, window[1]+1)) - offset
output.write(str(window_size) + " " + str("{0:.4f}".format(headerline)) + " " + 'L' + '\n')
for item in chunk:
newline = str("{0:.4f}".format(float(str(item).translate(None, "[]'"))-offset))
output.write(str(newline) + '\n')