需求:有一个1,500,000行数据的文件,需要进行多次检索。其中每行文件为一个列表,且每行列表的首位有序
问题:使用一般的循环检索方式,非常耗时,检索速度慢。
一、基础语法
1、拆分文件的路径和文件名
如要获取的文件绝对路径为:/aaa/aaa.txt,方法如下:
import os
filePath = "/aaa/aaa.txt"
array=os.path.split(filePath)
#得到的array由两部分组成,文件路径和文件名
print "array[0]:\n",array[0]
print "array[1]:\n",array[1]
'''
结果为:
array[0]:
/aaa
array[1]:
aaa.txt
'''
或者用下面的方法:
(filePath,fileName) = os.path.split(fileOriginPath)
2、拆分文件名主文件名和扩展名
(mainName,extension) = os.path.splitext(filePath)
print "mainName:\n",mainName
print "extension:\n",extension
'''
结果是:
mainName:
aaa
extension:
.txt
'''
二、大文件拆分
由于需求中文件行数过多,故考虑将文件进行拆分。
每100,000行为分割线,进行文件拆分。
话不多说,上代码
import os
#拆分大文件 100,000为分割
def getFilesFromOneFile(fileOriginName):
fileName = os.path.split(fileOriginName)[1]
mainName = os.path.splitext(fileName)[0]
target_dir = '/xxx/xxx/test/split_temp/'
#计数器
flag = 0
#文件名,用来生成以name为主文件名结尾的文件,区分每个分割文件
name = 0
#存放数据
dataList = []
with open(filename,'r') as f:
for line in f:
flag+=1
dataList.append(line)
if flag == 100000:
targetFile = target_dir+filename1+str(name)+".txt"
with open(targetFile,"w+") as f_target:
for data in dataList:
f_target.write(data)
name+=1
flag=0
dataList=[]
#处理最后一批行数少于100,000行的
rouNum = 0 #用于计算最后一个文件总行数
with open(target_dir+filename1+str(name)+".txt","w+") as f_target:
for data in dataList:
f_target.write(data)
rouNum += 1
pre_path=target_dir+fileName
fileNum=name
returnData.append(pre_path)#返回预设路径
returnData.append(fileNum)#返回最后文件的name
returnData.append(rowNum)#返回最后一个文件的总行数
return returnData
三、二分查找算法
拆分完文件后,再循环检索还是很浪费时间。好在文件的首列是有序的。故定位到分割文件后,再用二分查找算法进行检索。
例如,在文件中搜索首列为x所在行的内容:
#二分检索
def bin_search(data_set,val,rowNum):
#low和hign代表 最小下标,最大下标
low = 0
high = rowNum-1
while(low<=high):
mid=(low+high)//2
if data_set[mid]==val:
return mid
elif data_set[mid][0]>val:
high=mid-1
else:
low=mid+1
return #return null代表没找到
四、Main方法如下:
def readFile(fileName,index):
#根据索引,读取文件的指定行
with open(filename,'r') as f:
for line in f.readlines():
if line[0]==index:
return line
return
if "__name__"=="__main__":
file = "/aaa/aaa.txt" #file为含1,460,000行,每行三列数据的文件
returnData = getFilesFromOneFile(file)#将文件拆分成15个子文件
prePath = returnData[0]
fileNum = returnData[1]
lastRowNum = returnData[2]
fileIndex = x%100000
if fileIndex
结束啦~~~~