Ref: https://www.cnblogs.com/SeekHit/p/6245283.html
因爲有個需求,需要處理文件夾內所有txt文件,將txt裏面的數據篩選,重新存儲。
一.分析數據格式
需要處理的數據是txt格式存儲的。下圖中一行中的數據依次是,幀、時間、編號、特徵點編號、特徵點名字、特徵點世界座標x,y,z,特徵點屏幕座標x,y,一共32個特徵點,最後6個數據是頭部姿態的位置x,y,z和偏轉角度x,y,z。一行共計233個字段。
需要完成的工作是,把特徵點的編號,世界座標,屏幕座標分別寫入2個csv文件中。
因爲後面需要用到svm分類器,在數據挖掘軟件weka中進行分類。
二.Python文件讀取操作
需要做的是Python中txt文件讀取操作,然後利用split()函數將每行的字符串分割成元組,然後利用下標講我們需要保留的數據寫入到新的txt中。
常見的Python文件讀取txt的方法有3種:
方法一:
1 f = open("foo.txt") # 返回一個文件對象 2 line = f.readline() # 調用文件的 readline()方法 3 while line: 4 print line, # 後面跟 ',' 將忽略換行符 5 # print(line, end = '') # 在 Python 3中使用 6 line = f.readline() 7 8 f.close()
方法二:
1 for line in open("foo.txt"): 2 print line
方法三:
1 f = open("c:\\1.txt","r") 2 lines = f.readlines()#讀取全部內容 3 for line in lines 4 print line
因爲需要處理的數據最後一行不完整,所以,我們只處理到倒數第二行。用readlines()讀取到的是一個List,每行是一個元素。所以可以用len()方法統計有多少行,處理的時候處理到倒數第二行停止。
完成我們的需求:
1 def readFile(filepath): 2 f1 = open(filepath, "r") #打開傳進來的路徑 3 f_world = open("WorldData", "w") 4 f_image = open("ImageData", "w") 5 lines = f1.readlines() #讀取所有行 6 lines_count = len(lines) #統計行數 7 for n in range(0, lines_count-1): 8 line = lines[n] 9 line_object = line.split('\t') 10 11 i = 5 12 13 worldposition = "" 14 imageposition = "" 15 while i <= 223: #取值 16 id = line_object[i - 2] 17 world_x = line_object[i] 18 world_y = line_object[i + 1] 19 world_z = line_object[i + 2] 20 worldposition = id + " " + world_x + world_y + world_z 21 # print worldposition 22 f_world.write(worldposition) 23 24 image_x = line_object[i + 3] 25 image_y = line_object[i + 4] 26 imageposition = id + " " + image_x + image_y 27 f_image.write(imageposition) 28 29 i += 7 30 i -= 1 31 headposition = line_object[i - 1] + line_object[i] + line_object[i + 1] 32 headrotate = line_object[i + 2] + line_object[i + 3] + line_object[i + 4] 33 head = headposition + headrotate + "\n" 34 35 print head 36 f_world.write(head) # 寫入文件操作 37 f_image.write(head) 38 f1.close() 39 f_image.close() 40 f_world.close()
三.遞歸遍歷文件夾下多個txt文件
因爲需要處理的數據不止一個,用自動化的思想來解決這個問題,需要依次遍歷文件夾下多個txt文件。
代碼如下:
1 def eachFile(filepath): 2 pathDir = os.listdir(filepath) #獲取當前路徑下的文件名,返回List 3 for s in pathDir: 4 newDir=os.path.join(filepath,s) #將文件命加入到當前文件路徑後面 5 if os.path.isfile(newDir) : #如果是文件 6 if os.path.splitext(newDir)[1]==".txt": #判斷是否是txt 7 readFile(newDir) #讀文件 8 pass 9 else: 10 eachFile(newDir) #如果不是文件,遞歸這個文件夾的路徑
四.對處理得到的文件進行命名
需求是,處理完一個txt,如abc.txt,然後生成的文件,命名爲World_abc.txt和Image_abc.txt,並將生成的文件保存在和源文件同樣的目錄下面。
思路是,對路徑就行分割,使用
os.path.split(filepath)
返回的是一個2個元素的元祖,第一個元素是文件夾路徑,第二個是文件名。
1 nowDir = os.path.split(filepath)[0] #獲取路徑中的父文件夾路徑 2 fileName = os.path.split(filepath)[1] #獲取路徑中文件名 3 WorldDataDir = os.path.join(nowDir, "WorldData_" + fileName) #對新生成的文件進行命名的過程 4 ImageDataDir = os.path.join(nowDir, "ImageData_" + fileName) 5 6 f_world = open(WorldDataDir, "w") 7 f_image = open(ImageDataDir, "w")
處理完之後就嘩嘩譁生成一大堆了。
完整代碼:
#讀文件
import os
#處理文件數量
count=0
def readFile(filepath):
f1 = open(filepath, "r")
nowDir = os.path.split(filepath)[0] #獲取路徑中的父文件夾路徑
fileName = os.path.split(filepath)[1] #獲取路徑中文件名
WorldDataDir = os.path.join(nowDir, "WorldData_" + fileName) #對新生成的文件進行命名的過程
ImageDataDir = os.path.join(nowDir, "ImageData_" + fileName)
f_world = open(WorldDataDir, "w")
f_image = open(ImageDataDir, "w")
lines = f1.readlines()
lines_count = len(lines)
for n in range(0, lines_count-1):
line = lines[n]
line_object = line.split('\t')
i = 5
worldposition = ""
imageposition = ""
while i <= 223:
id = line_object[i - 2]
world_x = line_object[i]
world_y = line_object[i + 1]
world_z = line_object[i + 2]
worldposition = id + " " + world_x + world_y + world_z
# print worldposition
f_world.write(worldposition)
image_x = line_object[i + 3]
image_y = line_object[i + 4]
imageposition = id + " " + image_x + image_y
f_image.write(imageposition)
i += 7
i -= 1
headposition = line_object[i - 1] + line_object[i] + line_object[i + 1]
headrotate = line_object[i + 2] + line_object[i + 3] + line_object[i + 4]
head = headposition + headrotate + "\n"
print head
f_world.write(head)
f_image.write(head)
f_world.write("world")
f_image.write("image")
f1.close()
f_image.close()
f_world.close()
global count
count+=1
def eachFile(filepath):
pathDir = os.listdir(filepath) #獲取當前路徑下的文件名,返回List
for s in pathDir:
newDir=os.path.join(filepath,s) #將文件命加入到當前文件路徑後面
if os.path.isfile(newDir) : #如果是文件
if os.path.splitext(newDir)[1]==".txt": #判斷是否是txt
readFile(newDir) #讀文件
pass
else:
eachFile(newDir) #如果不是文件,遞歸這個文件夾的路徑
eachFile("D:\Python\SVM_Data")
print "共處理"+bytes(count)+"個txt"
補充:
代碼中添加了一個globle count變量,記錄處理的txt數目,因爲python語言是弱類型的語言,在函數中,想要改變全局遍歷的值。
1 count=0 2 def xxx(): 3 global count #聲明這裏的count是全局變量count 4 count+=1
最後輸出count數量的時候
1 print "共處理"+count+"個txt" #報錯,字符類型和值類型不能這樣輸出 2 3 print "共處理"+bytes(count)+"個txt" #使用bytes方法,將值類型轉換成字符類型
python OS模塊的官方文檔:
10.1. os.path — Common pathname manipulations — Python 2.7.13 documentation
https://docs.python.org/2.7/library/os.path.html