最近在作一個有關自然語言處理的project,要處理大量的語料文本,而python這種指令碼在處理字串上又有其無可比擬的優勢,所以就看了看這方面的書。以下是在做語料處理時遇到的一些問題,總結一下,也好以後再深入學習:
第一個問題就是大量文本讀入的問題,因為通過語料分詞處理後會產生大量的文字文件,想實現對這些文本的批處理,python中一個很好的包os幫了忙:
先在分詞程式中將處理後的文檔寫入到同一檔案夾下,這裡就是“c:\data”吧,然後通過下面的代碼實現:
import sysimport os def fun(path):#path 是路徑 for root,dirs,files in os.walk(path): for fn in files: filename="" filename=root+'\\'+fn
這裡的path就是"C:\data",檔案路徑作為參數輸入,得到的filename 就是這個檔案夾下的所有文檔了。
詳細的理解os.walk()這個方法,實際上它返回的是一個三元素的元組:當前路徑、子檔案夾名稱、檔案清單。這裡對應的就是root,dirs,files。到這裡我們自然會想到如果在data檔案下還有其他的子檔案夾,如果想遞迴找下去找到每個子檔案中的非檔案文檔該怎麼實現?好,帶這問題,我在data檔案夾下又放置了兩個子檔案data1和data2以及兩個文字文件datatext2.txt和datatext1.txt.其中data1下又有data3和datdtxt1.txt,data3中放有一個test.txt文檔。data2下放置了兩個文字文件datatext2.txt和datatext1.txt。要想找到最底層的那個文檔test.txt怎麼辦?
先找子檔案
import sysimport osdef fun(path): for root,dirs,files in os.walk(path): for dir in dirs: print dir
遺憾的是輸出的為
>>> fun(r'C:\data')
data1
data2
data3
也就是說這個方法能找到目前的目錄下的所有子檔案,但是如果我們要訪問test.txt,文檔路徑應該是"C:\data\data1\data3\test.txt",可是現在輸出的子檔案名稱並沒有體現層級,怎麼產生文本路徑呢,帶著試試的想法又去執行了下上面第一段代碼:
輸出:
>>> fun(r'C:\data')
C:\data\datatext2.txt
C:\data\datdtxt1.txt
C:\data\data1\datdtxt1.txt
C:\data\data1\data3\text.txt
C:\data\data2\datatext2.txt
C:\data\data2\datdtxt1.txt
這個結果如果是想遍曆目前的目錄下的所有文檔的話那就再好不過了,可是我要是只處理test.txt怎麼辦?以及要處理同以目錄級下的文檔該怎麼辦?先解決第二個問題,os中有很好的方法,讓我們可以對要訪問的文檔設定在同一目錄級下
例如,我現在只想訪問一級下的文檔,也就是"C:\data"下的文檔datatext2.txt和datatext1.txt(不包括子檔案下的文檔)
import sysimport globimport osdef fun(path): for fn in glob.glob(path+os.sep+'*'): if os.path.isfile(fn): filename="" filename=filename+fn print filename
輸出:
>>> fun(r'C:\data')
C:\data\datatext2.txt
C:\data\datdtxt1.txt
這裡用到了一個新的包glob和其中匹配方法glob();glob.glob()只接受一個參數,這個參數既代有路徑(path),又代有匹配模式('*'指的是所有檔案),傳回值是一個列表,包括了當前path下的所有子檔案,文檔。因為其不能直接穿透子檔案的原因給了我們靈活尋找文檔的功能。
那麼第一個問題呢?可以通過遞迴向下去找,也可以通過列出目錄檔案樹來找,但是都相對麻煩,既然os.walk()可以穿透到最底層,那麼可以利用這個性質
import sysimport osCOUNT=set()def fun(path): for root,dirs,files in os.walk(path): for fn in files: filename="" filename=root+'\\'+fn global COUNT COUNT.add(filename) DeepFile()def DeepFile(): temp1=set() deepnum=0 global COUNT for fn in COUNT: temp=[] temp=fn.split('\\') num=len(temp) if num==deepnum: temp1.add(fn) if num>deepnum: deepnum=num temp1.clear() temp1.add(fn) for fn in temp1: print fn
輸出:
>>> fun(r'C:\data')
C:\data\data1\data3\text.txt
以上代碼還有待改進,這種方法只能找到最底層檔案中的文檔
同時還總結了有關os包(python 檔案操作包)下的一些有用的方法:
python:目錄與檔案操作
os.listdir(dirname):列出dirname下的目錄和檔案
os.getcwd():獲得當前工作目錄
os.curdir:返回但前目錄('.')
os.chdir(dirname):改變工作目錄到dirname
os.path.isdir(name):判斷name是不是一個目錄,name不是目錄就返回false
os.path.isfile(name):判斷name是不是一個檔案,不存在name也返回false
os.path.exists(name):判斷是否存在檔案或目錄name
os.path.getsize(name):獲得檔案大小,如果name是目錄返回0L
os.path.abspath(name):獲得絕對路徑
os.path.normpath(path):規範path字串形式
os.path.split(name):分割檔案名稱與目錄(事實上,如果你完全使用目錄,它也會將最後一個目錄作為檔案名稱而分離,同時它不會判斷檔案或目錄是否存在)
os.path.splitext():分離檔案名稱與副檔名
os.path.join(path,name):串連目錄與檔案名稱或目錄
os.path.basename(path):返迴文件名
os.path.dirname(path):返迴文件路徑