项目中需要读取一个pickle数据文件,pickle文件存储的是按行保存的文本,需要调用编码模型分别对每一条文本进行编码,然后使用numpy数组保存编码后的向量。由于模型每次只能输入一定batch size大小的数据,所以需要对数据继续分割后再输入模型编码向量,可以直接加载整个文件,通过batch size来分割整个文件数组。但是如果文件很大,这样的加载方式可能会导致内存溢出。因此考虑对文件进行单行读取,使用一个队列来接受读取的数据,当读取的行数等于batch size时,就将这个批次的数据送入模型进行编码。

于是自己写了一个简单的队列实现批量数据进入队列,队列满了之后清空队列,但与一般的队列不同,只使用一个index的指针来表示队尾巴,并实时返回队列是否已满(此处可以优化)。

队列代码

class data_queue(object):

    def __init__(self,size,init_v = ""):
        self.init_v = init_v
        self.size = size
        self.data = [init_v]*size
        self.index = -1
        self.isFull = False
        self.over_v = init_v

    def put(self,value):
        self.index += 1
        self.data[self.index] = value

        if self.index == self.size-1:
            self.isFull = True
            self.over_v = value

        return self.isFull

    def pop(self):
        if self.index < 0:
            raise ValueError("队列为空不能删除")

        # 从队首删除元素,后面的数据往前移
        remain_data = self.data[1:self.index+1]
        self.data[self.index] = self.init_v
        self.data[:self.index] = remain_data

        self.index -= 1

    def pop_all(self):
        if self.index < 0:
            raise ValueError("队列为空不能删除")

        for i in range(self.index,-1,-1):
            self.data[i] = self.init_v
            self.index -=1

        self.isFull = False

    def show_data(self):
        print(self.index,self.data)
调用测试代码
#测试队列
data_list = [x*3 for x in "abcdefghijklmn"]
    # 初始化队列
    ds_q = data_queue(10)
    tmp = []
    for ele in data_list:
        is_full = ds_q.put(ele)
        ds_q.show_data()

        if ele == "f"*3 or ele == "l"*3:
            ds_q.pop()
            print("出队一个元素")

        if is_full:
            print("队列已满,返回队列中的值并清空队列")
            tmp = ds_q.data
            ds_q.pop_all()

从调用结果来看,实现了队列的功能,在队列满队时就触发pop_all的操作,将所有的队列元素全部弹出去消费,将整个队列清空。因为我在实际使用时不使用pop单个元素的情况,所以编写出队操作的代码比较简单,直接将队头元素出队,整体移动后面的队列元素。但如果需要频繁出队就需要考虑性能,一般会设置队头指针,出队时对头指针往后移动,只有当队尾指针满队时再整体移动队列元素,或者使用循环队列,这个需要根据自己的需求来编写代码。

#测试结果
0 ['aaa', '', '', '', '', '', '', '', '', '']
1 ['aaa', 'bbb', '', '', '', '', '', '', '', '']
2 ['aaa', 'bbb', 'ccc', '', '', '', '', '', '', '']
3 ['aaa', 'bbb', 'ccc', 'ddd', '', '', '', '', '', '']
4 ['aaa', 'bbb', 'ccc', 'ddd', 'eee', '', '', '', '', '']
5 ['aaa', 'bbb', 'ccc', 'ddd', 'eee', 'fff', '', '', '', '']
出队一个元素
5 ['bbb', 'ccc', 'ddd', 'eee', 'fff', 'ggg', '', '', '', '']
6 ['bbb', 'ccc', 'ddd', 'eee', 'fff', 'ggg', 'hhh', '', '', '']
7 ['bbb', 'ccc', 'ddd', 'eee', 'fff', 'ggg', 'hhh', 'iii', '', '']
8 ['bbb', 'ccc', 'ddd', 'eee', 'fff', 'ggg', 'hhh', 'iii', 'jjj', '']
9 ['bbb', 'ccc', 'ddd', 'eee', 'fff', 'ggg', 'hhh', 'iii', 'jjj', 'kkk']
队列已满,返回队列中的值并清空队列
0 ['lll', '', '', '', '', '', '', '', '', '']
出队一个元素
0 ['mmm', '', '', '', '', '', '', '', '', '']
1 ['mmm', 'nnn', '', '', '', '', '', '', '', '']