Python 如何编写步长为0的滑动窗口算法?

Python 如何编写步长为0的滑动窗口算法?,python,algorithm,text,range,sliding-window,Python,Algorithm,Text,Range,Sliding Window,我正在处理一个大的文本文件,其中包含具有这种格式的pi的小数位数。请注意,标题是所有数字,没有字符串 标题格式:序列号总位数文件版本号 550 10000 5 *Pi Sequence Part 1 1415926535897932384 *Pi Sequence Part 2 6264338327950288419 *Pi Sequence Part 3 1693993751058209749 我需要制作一个滑动窗口,使用三个参数(window\u size、step\u size和las

我正在处理一个大的文本文件,其中包含具有这种格式的pi的小数位数。请注意,标题是所有数字,没有字符串

标题格式:序列号总位数文件版本号

550 10000 5

*Pi Sequence Part 1
1415926535897932384
*Pi Sequence Part 2
6264338327950288419
*Pi Sequence Part 3
1693993751058209749
我需要制作一个滑动窗口,使用三个参数(window\u size、step\u size和last\u windowstart)裁剪文件。last_WindowsStart是最后一个窗口的开始位置

文件的数量是通过将总位数除以窗口来确定的

如果文件的总位数为99,窗口大小为10,步长大小为零,则总共有11个窗口,因为99//10=10,99%的10在窗口11中留下9个窗口

对于这个例子,我想lastwindow\u start应该是90。我不确定我是否需要启动最后一个窗口

对于每个窗口,将创建一个名为PiSubsection的文件# 其中#是窗口号

对于每个文件,每个窗口都应具有相同的新标题,其中标题格式为\u序列总数\u Pi\u数字文件\u版本\u编号

序列总数将根据窗口大小和步长大小而改变,但文件版本号不得改变

我的问题是,我的滑动窗口算法没有考虑步长为0的情况,并且它没有生成正确数量的文件。 到目前为止,它生成的文件是以前的两倍,我不知道为什么

此外,我不确定我是否理解滑动窗口算法中窗口数量的数学

如何修正滑动窗口算法以接受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')

下面的示例代码提供了一种替代方法,可以避免进行计算。我认为加载数字文件或之后实际写入“窗口”文件都没有问题,因此我的代码假设它们已加载,并生成一个准备写入的数字窗口数组

根据这个结果,您可以简单地迭代现在派生的窗口并像以前一样输出文件,或者您可以深入嵌套的数据并获得单独的窗口,以便根据需要进行处理

下面是示例输出。如果需要更多细节,请告诉我

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)
样本输出:

编辑

为了避免我的假设过多,这里有一个片段来解析加载的数字文件:

# 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_数字随时可用,因此您可以用它替换上面代码中的
pi_数字声明。

下面的示例代码提供了一种替代方法,可以避免进行计算。我认为加载数字文件或之后实际写入“窗口”文件都没有问题,因此我的代码假设它们已加载,并生成一个准备写入的数字窗口数组

根据这个结果,您可以简单地迭代现在派生的窗口并像以前一样输出文件,或者您可以深入嵌套的数据并获得单独的窗口,以便根据需要进行处理

下面是示例输出。如果需要更多细节,请告诉我

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)
样本输出:

编辑

为了避免我的假设过多,这里有一个片段来解析加载的数字文件:

# 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_数字随时可用,因此您可以用它替换上面代码中的
pi_数字声明。

解决方案是将文件存储在列表中,然后使用该列表的块和滑动窗口生成器来创建所有小文件

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')

解决方案是将文件存储在一个列表中,然后使用该列表的块和滑动窗口生成器来创建所有小文件

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')

您对滑动窗口的概念是否与此处描述的相同?而且,在我看来,步长必须至少为1,否则算法将保持在相同的索引上?是的。这就是我所困惑的。问题是它确实创建了正确数量的文件。您对滑动窗口的概念是否与此处描述的相同?而且,在我看来,步长必须至少为1,否则算法将保持在相同的索引上?是的。这就是我所困惑的。问题是它确实创建了正确数量的文件。