(python)大量数据乱序思路以及核心代码

3 篇文章 0 订阅
2 篇文章 0 订阅

一、前言

笔者做过一次项目,其中要求对几十亿条数据顺序乱序。做这个项目的时候,笔者切实的感到了大量数据和少量数据的不同。受到时间和空间条件的制约,我们无法将所有数据放到内存中的时候,或者说即便放进去速度也不符合要求的时候,就迫使我们想别的办法。

二、思路

1、少量数据乱序是有函数的,在Ubuntu中有“shuffle”,python中导入random模块之后,对列表list乱序的操作为:random.shuffle(list),在笔者电脑上测试的时候,每次处理200w行数据的乱序的时候还是比较合适的,再大就变慢很多了。
另外我们也可以利用集合set()无序的特点,将列表转化为set()再转化回列表,但这样效果不好结果也得不到保证,因此不推荐使用。
2、大量数据乱序的时候,我们可以用“分而治之”的思路,将数据顺序截取分解存储在100w/个的文件里。
3、使用os模块将文件名存储在列表中,对这个文件名列表进行乱序。
4、按照文件名列表打乱后的顺序,每两个文件拼接存储到一个列表中,组成一个200w的列表,对这个列表乱序,然后平分写回文件,依此类推。

三、优点

1、利用系统函数shuffle,以及分治思想,节约了大量的时间和空间。
2、这样循环一遍之后,每个文件中都含有200w的1/2,重复步骤3、4。理想状态下,下次循环完每个文件中将存有400w的1/4,再下一次将含有800w的1/8,指数增长,从而较快达到乱序的目的。
3、在尽量不影响速度的前提下,将文件存储的尽可能大,可以减少开闭文件耗费的时间。

4、核心代码

import random
import os
import time

#建立10个顺序文件
def write_files(Filepath):
    num,n=0,0
    while(num<10):
        f1=open(Filepath+str(num)+".txt","w")
        for i in range(n,n+100):
            f1.write(str(i)+"\n")
        f1.close()
        num+=1
        n+=100

        


#将列表切割成一半,因为n是list_file长度的一半
def cut_list(list_file, n):
    list1,list2=list_file[0:n],list_file[n:]
    return [list1,list2]

#文件之间乱序,然后切割
def exchange_ips(Filepath):
    pathDir =  os.listdir(Filepath)
    random.shuffle(pathDir)
    file_index,l=0,len(pathDir)
    #按照此时顺序,文件之间两两交换
    while(file_index+1<l):
        filepath1=Filepath+pathDir[file_index]
        filepath2=Filepath+pathDir[file_index+1]
        list_file1,list_file2=[],[]
        f1=open(filepath1,"r+")
        for line in f1:
            list_file1.append(line)
        f2=open(filepath2,"r+")
        for line in f2:
            list_file2.append(line)
        #利用集合快速拼接,同时初步乱序,还有去重的效果
        list_file=list(set(list_file1).union(set(list_file2)))
        half_size=int((len(list_file1)+len(list_file2))/2)
        random.shuffle(list_file)
        list_file1,list_file2=cut_list(list_file,half_size)
        f1.seek(0)
        f1.truncate()   #清空文件
        f2.seek(0)
        f2.truncate()   #清空文件
        for item in list_file1:
            f1.write(item)
        for item in list_file2:
            f2.write(item)
        f1.close()
        f2.close()
        file_index+=1
        print(pathDir[file_index-1]+" and "+pathDir[file_index]+" exchange ok~")

if __name__ == '__main__':
    Filepath="F:\\测试文件夹\\"
    #建立10个顺序文件
    write_files(Filepath)
    a=10
    #进行10次乱序
    while(a>0):
        a=a-1
        exchange_ips(Filepath)

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值