大文件里面内容的快速查找(数据分析案例二)

本内容是基于上篇博客 装饰器 的基础上写的。
上篇博客侧重于装饰器
本博客侧重于文件内容的迅速查找



  • 本节内容的数据见电脑F:\python数据\Python海量数据(精缩版)百度网盘“我的数据文件/Python海量数据”

七、普通查找、二分查找、拉格朗日查找

10000个人中有一个人得了新冠肺炎,你要筛选那一个人总不可能是一个一个检测吧?
将10000分成两拨,五千个一起检测,然后把有病毒的5000个样本中分成两拨,2500个的检测。。。
这就是2分查找
拉格朗日查找就是2分查找的公式改变
在这里插入图片描述
1.普通的方式查找一个数

import time
def  costTime(func):
    def _costTime(finddata,findlist):
        starttime=time.time()
        func(finddata,findlist)
        endtime=time.time()
        print(endtime-starttime)
    return _costTime


@costTime
def search(finddata,findlist):
    for data in findlist:
        if data==finddata:
            print("find",data)
            return
    print("not find")


findlist=[x for  x in range(100000)]
while True:
    finddata=eval(input("data"))
    search(finddata,findlist) 

在这里插入图片描述

2.用二分查找

import time
def  costTime(func):
    def _costTime(finddata,findlist):
        starttime=time.time()
        func(finddata,findlist)
        endtime=time.time()
        print(endtime-starttime)
    return _costTime

@costTime  #这是2分查找,2分查找就是在0-100里面找56的位置时,直接比较(0+100)/2=50和56的大小
def search2(finddata,findlist):
    low=0  #第一个
    high=len(findlist)-1 #代表最后一个

    times=0
    while low<=high: #不能重叠
        times+=1
        print("times",times)  #记录查询的次数 
        mid=(low+high)//2  #取出中间索引
        middata=findlist[mid] #取出中间数据
        if  finddata <middata: #小于 淘汰1半
            high =mid-1
        elif finddata >middata: #小于 淘汰1半
            low =mid+1
        else:
            print("find",finddata,mid)
            return mid
    print("not find")
    return -1

findlist=[x for  x in range(100000)]
while True:
    finddata=eval(input("data"))
    search2(finddata,findlist) 

在这里插入图片描述


import time
def  costTime(func):
    def _costTime(finddata,findlist):
        starttime=time.time()
        func(finddata,findlist)
        endtime=time.time()
        print(endtime-starttime)
    return _costTime


@costTime  #这是拉格朗日的查找方法
def search2lr(finddata,findlist):
    low=0  #第一个
    high=len(findlist)-1 #代表最后一个

    times=0
    while low<=high: #不能重叠
        times+=1
        print("times",times)

        #mid=(low+high)//2  #取出中间索引
        datamid=((finddata-low)/(high-low))
        mid = int(low + (high - low) * datamid)
        middata=findlist[mid] #取出中间数据
        if  finddata <middata: #小于 淘汰1半
            high =mid-1
        elif finddata >middata: #小于 淘汰1半
            low =mid+1
        else:
            print("find",finddata,mid)
            return mid
    print("not find")
    return -1


findlist=[x for  x in range(100000)]
while True:
    finddata=eval(input("data"))
    search2lr(finddata,findlist) 

在这里插入图片描述

八、例题

1.先对文件进行排序
//我们把csdn里面的数据按照用户的字母顺序排序
在这里插入图片描述

def getuser(line):
    line=line.decode("gbk","ignore")
    linelist=line.split(" # ")
    return linelist[0]


inputfilepath="E:\python数据分析\百度网盘\Python数据分析海量数据营销day2\Python数据分析海量数据营销day2\Search\csdn.txt"
outputfilepath="E:\python数据分析\百度网盘\Python数据分析海量数据营销day2\Python数据分析海量数据营销day2\Search\csdnsortbyuser.txt"
csdninputfile=open(inputfilepath,"rb")
csdnlist=csdninputfile.readlines()
csdninputfile.close()
print("读取完成")
csdnlist.sort(key=lambda x :getuser(x))
print("排序完成")
csdnoutputfile=open(outputfilepath,"wb")
for  line  in csdnlist:
    csdnoutputfile.write(line)
csdnoutputfile.close()

在这里插入图片描述
2.快速查询文件里面的某一行内容

在这里插入图片描述

filepath="E:\python数据分析\百度网盘\Python数据分析海量数据营销day2\Python数据分析海量数据营销day2\Search\csdnsortbyuser.txt"
csdninputfile=open(filepath,"rb")
csdnlist=csdninputfile.readlines()


lengthlist=[0]  #第一行的索引为0
for  line in csdnlist:
    lengthlist.append(len(line)) #读取每一行的长度到数组


i=1
length=len(lengthlist)
while i <length -1:  #舍弃了最后一行
    lengthlist[i]=lengthlist[i-1]+lengthlist[i] #叠加,确定每一行的文件位置
    i+=1

while True:
    linenum=eval(input("input lines: "))  #输入你想直接跳到的行数
    csdninputfile.seek(lengthlist[linenum-1],0) #seek可以直接跳到某一行的位置
    line=csdninputfile.readline()#读取那一行的信息
    print(line)

csdninputfile.close()

在这里插入图片描述
在这里插入图片描述
3.利用二分查找,根据文件里面的某一行内容快速定位这一行所在的位置


def search2(searchstr,lengthlist):
    low = 0  # 第一个
    high = len(lengthlist) - 1  # 代表最后一个

    times = 0
    while low <= high:  # 不能重叠
        times += 1
        print("times", times)
        mid = (low + high) // 2  # 取出中间索引

        midindex=lengthlist[mid] #取出位置,
        csdninputfile.seek(midindex,0) #移动到位置
        line=csdninputfile.readline() #读取以行
        line=line.decode("gbk","ignore") #解码
        linelist=line.split(" # ")#切割
        middata=linelist[0] #挖出user,按照user

        if searchstr< middata:  # 小于 淘汰1半
            high = mid - 1
        elif searchstr > middata:  # 小于 淘汰1半
            low = mid + 1
        else:
            print("find", line, mid)
            return mid
    print("not find")
    return -1


filepath="E:\python数据分析\百度网盘\Python数据分析海量数据营销day2\Python数据分析海量数据营销day2\Search\csdnsortbyuser.txt"
csdninputfile=open(filepath,"rb")
csdnlist=csdninputfile.readlines()


lengthlist=[0]
for  line in csdnlist:
    lengthlist.append(len(line)) #读取每一行的长度到数组


i=1
length=len(lengthlist)
while i <length -1:
    lengthlist[i]+=lengthlist[i-1] #叠加,确定每一行的文件位置
    i+=1
print("索引生成了")

while True:
   searchstr=input("input data:  ")  #根据用户名查找,你输入一个存在的用户名然后来查找
   search2(searchstr,lengthlist)

csdninputfile.close()

在这里插入图片描述




上面的内容是基于几百万的数据,你可以把索引存到一个列表里,下面我们要搞17亿的数据
基本思想是根据文件里面的数据生成一个索引文件(把索引放到文件里),根据索引文件来查找那些特定行的数据
在这里插入图片描述

一、根据数据生成索引文件

filepath="E:\python数据分析\百度网盘\Python数据分析海量数据营销day3\Python数据分析海量数据营销day3\Search\csdnsortbyuser.txt"
csdninputfile=open(filepath,"rb")
csdnlist=csdninputfile.readlines()

lengthlist=[0]
for  line in csdnlist:
    lengthlist.append(len(line)) #读取每一行的长度到数组

i=1
length=len(lengthlist)
while i <length -1:
    lengthlist[i]+=lengthlist[i-1] #叠加,确定每一行的文件位置
    i+=1
indexfilepath="E:\python数据分析\百度网盘\Python数据分析海量数据营销day3\Python数据分析海量数据营销day3\Search\csdnsortbyuserindex.txt"
saveindexfile=open(indexfilepath,"wb")
for  i  in range(len(lengthlist)-1):
    saveindexfile.write(format(lengthlist[i],"10d").encode("utf-8"))#保存为等长,为了随机访问(我们知道原文件每一行都不是等长的,我们生成的索引文件里面的每个数据就必须是等长的,方便查找)
saveindexfile.close()
csdninputfile.close()

在这里插入图片描述

二、根据索引文件快速访问某一行数据


csdnfilepath="E:\python数据分析\百度网盘\Python数据分析海量数据营销day3\Python数据分析海量数据营销day3\Search\csdnsortbyuser.txt"
csdnindexfilepath="E:\python数据分析\百度网盘\Python数据分析海量数据营销day3\Python数据分析海量数据营销day3\Search\csdnsortbyuserindex.txt"
csdnfile=open(csdnfilepath,"rb")
csdnindexfile=open(csdnindexfilepath,"rb")

while True:
    linenum=eval(input("input lines:  "))
    csdnindexfile.seek(10*(linenum-1),0) #跳到索引文件的中间位置(别忘了你之前保存的时候是按照"10d"的方式保存的)
    lineval=csdnindexfile.read(10)#读取10个字符
    lineval=eval(lineval)#转化为数字

    csdnfile.seek(lineval,0) #根据索引取出位置
    line=csdnfile.readline()
    line=line.decode("gbk","ignore")
    print(line)




csdnindexfile.close()
csdnfile.close()

在这里插入图片描述

三、利用二分查找,根据文件里面的某一行内容快速定位这一行所在的位置

def search2(searchstr):
    low = 0  # 第一个
    high = 6428632-1  # 代表最后一个

    times = 0
    while low <= high:  # 不能重叠
        times += 1
        print("times", times)
        mid = (low + high) // 2  # 取出中间索引

        csdnindexfile.seek(10 * (mid - 1), 0)  # 跳到索引文件的中间位置
        lineval = csdnindexfile.read(10)  # 读取10个字符
        lineval = eval(lineval)  # 转化为数字

        csdnfile.seek(lineval, 0)  # 根据索引取出位置
        line = csdnfile.readline()
        line = line.decode("gbk", "ignore")
        linelist=line.split(" # ")
        middata=linelist[0]

        if searchstr< middata:  # 小于 淘汰1半
            high = mid - 1
        elif searchstr > middata:  # 小于 淘汰1半
            low = mid + 1
        else:
            print("find", line, mid)
            return mid
    print("not find")
    return -1



csdnfilepath="E:\python数据分析\百度网盘\Python数据分析海量数据营销day3\Python数据分析海量数据营销day3\Search\csdnsortbyuser.txt"
csdnindexfilepath="E:\python数据分析\百度网盘\Python数据分析海量数据营销day3\Python数据分析海量数据营销day3\Search\csdnsortbyuserindex.txt"
csdnfile=open(csdnfilepath,"rb")
csdnindexfile=open(csdnindexfilepath,"rb")

while True:
    searchstr=input("input searchstr: ")
    search2(searchstr)


csdnindexfile.close()
csdnfile.close()

在这里插入图片描述




一、倒排索引

在这里插入图片描述

def getuser(num):
    csdninputfile.seek(num,0)  #跳到文件的位置。根据文件排序
    line=csdninputfile.readline()
    line=line.decode("gbk","ignore")
    linelist=line.split(" # ")
    return linelist[0]

filepath="E:\python数据分析\百度网盘\Python数据分析海量数据营销day3\Python数据分析海量数据营销day3\Search\csdn.txt"
csdninputfile=open(filepath,"rb")
csdnlist=csdninputfile.readlines()

lengthlist=[0]
for  line in csdnlist:
    lengthlist.append(len(line)) #读取每一行的长度到数组

i=1
length=len(lengthlist)
while i <length -1:
    lengthlist[i]+=lengthlist[i-1] #叠加,确定每一行的文件位置
    i+=1

lengthlist.sort(key=lambda x:getuser(x))#根据文件排序索引,
'''
csdninputfile是原文件,lengthlist是索引
注意:lengthlist.sort(key=lambda x:getuser(x))中的x是索引列表lenglist里的每一个元素,getuser(x)就是根据索引得到对应的csdninputfile里的那一行的元素,
lengthlist.sort(key=lambda x:getuser(x))的计算机理是先算key=lambda x:getuser(x)再算lengthlist.sort()

C = [('e', 4, 2), ('a', 2, 1), ('c', 5, 4), ('b', 3, 3), ('d', 1, 5)]
print(sorted(C, key=lambda x: x[2]))
[('a', 2, 1), ('e', 4, 2), ('b', 3, 3), ('c', 5, 4), ('d', 1, 5)]
'''

print("index made")
while True:
    linenum=eval(input("input lines"))
    csdninputfile.seek(lengthlist[linenum],0) #跳到某一行的位置
    line=csdninputfile.readline()#读取1行
    print(line)

csdninputfile.close()

在这里插入图片描述

二、生成倒排索引文件

def getuser(num):
    csdninputfile.seek(num,0)  #跳到文件的位置。根据文件排序
    line=csdninputfile.readline()
    line=line.decode("gbk","ignore")
    linelist=line.split(" # ")
    return linelist[0]

filepath="E:\python数据分析\百度网盘\Python数据分析海量数据营销day3\Python数据分析海量数据营销day3\Search\csdn.txt"
csdninputfile=open(filepath,"rb")
csdnlist=csdninputfile.readlines()

lengthlist=[0]
for  line in csdnlist:
    lengthlist.append(len(line)) #读取每一行的长度到数组
del  csdnlist #及时清理不用的东西,清理内存


i=0
length=len(lengthlist)
while i <length -1:
    lengthlist[i+1]+=lengthlist[i] #叠加,确定每一行的文件位置
    i+=1
del lengthlist[len(lengthlist)-1] #删除最后一个(你可以看看,最后一个就不是索引了)

lengthlist.sort(key=lambda x:getuser(x))#根据文件排序索引,

print("index made")
indexfilepath="E:\python数据分析\百度网盘\Python数据分析海量数据营销day3\Python数据分析海量数据营销day3\Search\csdnsortindex.txt"
saveindexfile=open(indexfilepath,"wb")
for  i  in range(len(lengthlist)-1):
    #保存为等长,为了随机访问
    saveindexfile.write(format(lengthlist[i],"10d").encode("utf-8")) #按照十个字节的长度存储进去
saveindexfile.close()

在这里插入图片描述

三、用二分查找

1.内存二分查找
什么叫做内存二分查找?你把索引存放到一个列表lengthlist里,这不就是存到内存里了吗?
什么叫硬盘二分查找?你把索引存放到一个文件里面,这不就是存放到硬盘里了吗?

倒排索引就相当于对原文件按照字符串大小进行排好序了,只要是按照文件内容排好序的都可以用2分查找快速定位


def search2(searchstr,lengthlist):
    low = 0  # 第一个
    high = len(lengthlist) - 1  # 代表最后一个

    times = 0
    while low <= high:  # 不能重叠
        times += 1
        print("times", times)
        mid = (low + high) // 2  # 取出中间索引

        midindex=lengthlist[mid] #取出位置,
        csdninputfile.seek(midindex,0) #移动到位置
        line=csdninputfile.readline() #读取以行
        line=line.decode("gbk","ignore") #解码
        linelist=line.split(" # ")#切割
        middata=linelist[0] #挖出user,按照user

        if searchstr< middata:  # 小于 淘汰1半
            high = mid - 1
        elif searchstr > middata:  # 小于 淘汰1半
            low = mid + 1
        else:
            print("find", line, mid)
            return mid
    print("not find")
    return -1

def getuser(num):
    csdninputfile.seek(num,0)  #跳到文件的位置。根据文件排序
    line=csdninputfile.readline()
    line=line.decode("gbk","ignore")
    linelist=line.split(" # ")
    return linelist[0]

filepath="E:\python数据分析\百度网盘\Python数据分析海量数据营销day3\Python数据分析海量数据营销day3\Search\csdn.txt"
csdninputfile=open(filepath,"rb")
csdnlist=csdninputfile.readlines()

lengthlist=[0]
for  line in csdnlist:
    lengthlist.append(len(line)) #读取每一行的长度到数组
del  csdnlist


i=0
length=len(lengthlist)
while i <length -1:
    lengthlist[i+1]+=lengthlist[i] #叠加,确定每一行的文件位置
    i+=1
del lengthlist[len(lengthlist)-1] #删除最后一个

lengthlist.sort(key=lambda x:getuser(x))#根据文件排序索引,

print("index made")

while True:
   searchstr=input("input data")
   search2(searchstr,lengthlist)

csdninputfile.close()

在这里插入图片描述
2.硬盘二分查找
什么叫做内存二分查找?你把索引存放到一个列表lengthlist里,这不就是存到内存里了吗?
什么叫硬盘二分查找?你把索引存放到一个文件里面,这不就是存放到硬盘里了吗?

def search2(searchstr):
    low = 0  # 第一个
    high = 6428632-1  # 代表最后一个

    times = 0
    while low <= high:  # 不能重叠
        times += 1
        print("times", times)
        mid = (low + high) // 2  # 取出中间索引

        csdnindexfile.seek(10 * (mid - 1), 0)  # 跳到索引文件的中间位置
        lineval = csdnindexfile.read(10)  # 读取10个字符
        lineval = eval(lineval)  # 转化为数字

        csdnfile.seek(lineval, 0)  # 根据索引取出位置
        line = csdnfile.readline()
        line = line.decode("gbk", "ignore")
        linelist=line.split(" # ")
        middata=linelist[0]

        if searchstr< middata:  # 小于 淘汰1半
            high = mid - 1
        elif searchstr > middata:  # 小于 淘汰1半
            low = mid + 1
        else:
            print("find", line, mid)
            return mid
    print("not find")
    return -1



csdnfilepath="E:\python数据分析\百度网盘\Python数据分析海量数据营销day3\Python数据分析海量数据营销day3\Search\csdn.txt"
csdnindexfilepath="E:\python数据分析\百度网盘\Python数据分析海量数据营销day3\Python数据分析海量数据营销day3\Search\csdnsortindex.txt"
csdnfile=open(csdnfilepath,"rb")
csdnindexfile=open(csdnindexfilepath,"rb")

while True:
    searchstr=input("input searchstr: ")
    search2(searchstr)


csdnindexfile.close()
csdnfile.close()

在这里插入图片描述

微信扫码订阅
UP更新不错过~
关注
  • 0
    点赞
  • 1
    收藏
  • 打赏
    打赏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
©️2022 CSDN 皮肤主题:黑客帝国 设计师:我叫白小胖 返回首页
评论 1

打赏作者

BlackHur

你的鼓励将是我创作的最大动力

¥2 ¥4 ¥6 ¥10 ¥20
输入1-500的整数
余额支付 (余额:-- )
扫码支付
扫码支付:¥2
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值