Пока я твердо знаю, только то, что при парсинге интернет у меня в компьютере будет собираться уйма "сырых" файлов, из которых я буду компоновать новые файлы-таблицы... Через 3-5 месяцев мне будет трудно вспомнить, что и зачем я делал, где и что лежит... Как не забивать свой винчестер таким мусором? Как разложить все по полочкам?
Я уже знаю, что есть интересные возможности для работы со специальными базами данных... Но для начала разберемся с текстовыми файлами.
Сейчас у меня довольно смутное представление не только о том, как организовать работу с файлами, но и о конкретных командах (функциях, модулях) языка Питон. Наверняка, есть несколько вариантов... Потому будем одновременно рассматривать две "разных" темы: постановка задачи, модули Питон..., и не стоит отказываться от попыток найти пользователскую библиотеку для организации хранилища текстовых файлов.
Постановка задачи: файлы CSV, первое приближение¶
В данный момент мне нравится вот такая схема работы с файлами:
0. В отдельные подпаки проекта скачиваем исходные файлы CSV с одинаковыми таблицами (число и порядок столбцов совпадают)
00. Таким образом, исходные данные могут хранится в дереве папок.
...
1. Задаем папку и в ней (и в подпапках) находим все файлы, удовлетворяющие нескольким параметрам-условиям.
2. Параметры файла мы кодируем в его имени (имя - это строка_с_разделителями), условие поиска - маска строки.
3. Формируем список имен файлов для обработки и предаем его модулям - конвертерам (обработчикам), результаты записываем в другие папки.
4. Важную роль играют соглашения об именах папок и форматах таблиц данных (их лучше записывать в манифесты)
0. В отдельные подпаки проекта скачиваем исходные файлы CSV с одинаковыми таблицами (число и порядок столбцов совпадают)
00. Таким образом, исходные данные могут хранится в дереве папок.
...
1. Задаем папку и в ней (и в подпапках) находим все файлы, удовлетворяющие нескольким параметрам-условиям.
2. Параметры файла мы кодируем в его имени (имя - это строка_с_разделителями), условие поиска - маска строки.
3. Формируем список имен файлов для обработки и предаем его модулям - конвертерам (обработчикам), результаты записываем в другие папки.
4. Важную роль играют соглашения об именах папок и форматах таблиц данных (их лучше записывать в манифесты)
Модули: Перебираем файлы в папке¶
Сначала найдем несколько примеров: Directory listing in Python Calling an external command in Python - не смог пропустить, здесь много примеров How to list all files of a directory in Python ... этот последний и возьмем за основу
Здесь рассматриваются варианты os.listdir(), glob, dircache, path... в зависимости от того, выбрать файлы из одной директории или поддерева директорий, отделить файлы от папок...
Пока будем считать, что все нашаи файлы только в одной папке, все файлы однотипные (например, однотипные CSV таблицы ...две первые строки пустые, далее - строка заголовка, столбцы одинаковые везде...)
Пока будем считать, что все нашаи файлы только в одной папке, все файлы однотипные (например, однотипные CSV таблицы ...две первые строки пустые, далее - строка заголовка, столбцы одинаковые везде...)
In []:
# I have to know, where am I ... I have to decide absolute or relative filepath I am going to use...
In [4]:
from os import listdir
from os.path import isfile, join
mypath='C:\\Users\\kiss\\Documents\\IPython Notebooks\\web\\raw_to_csv'
onlyfiles = [ f for f in listdir(mypath) if isfile(join(mypath,f)) ]
In [5]:
onlyfiles
Out[5]:
Модули: Пока есть сомнения насчет конструкции " ...if isfile(join(mypath,f) ...", надо буде разобраться... Пока просто посмотрим на эти функции:¶
In [10]:
help(listdir)
In [11]:
help(isfile)
In [12]:
help(join)
Откуда берутся эти "новые" модули..., например, ntpath ??? Они, либо из системных библиотек, либо вызываются в OS (мы импоритровали из этого модуля) и наследуются там... Посмотрим:
In [15]:
os.path??
In []:
#..... Да из os.path вызывается изрфдное количесвто модулей
import os
import sys
import stat
import genericpath
import warnings
from genericpath import *
.....
Ниже в этом посте я еще раз импортирую os ... Делать этого не надо было, я просто тупо скопировал код из чужого примера...
Возвращаемся к постановке задачи¶
Итак, мы получили список файлов в директории, теперь мы можем организовать итерации по этому списку, чтобы сделать что-нибудь с каждым файлом), а потом записать новый файл в новую (соседнюю?) папку.
По умолчанию рабочая директория там, откуда мы запустили ipython..., или ее можно настроить..., или задать программно базовый путь... и к нему приклеивать относительные... Пока не знаю, как лучше..., потому договоримся, что, дабы не путаться... каждый раз будем запускать Питон из папки проектов. Получается, что еще проще задавать базовый (абсолютный путь), как в grab...
Вот примеры кода определеним абсолютного и относительного пути How to get an absolute file path in Python
In [7]:
# Сначала найдем текущую рабочую папку, чтобы выбрать имя реального файла (см. ячейку ниже)
!chcp 65001
!dir
Можно получить абсолютный путь... из относительного http://stackoverflow.com/questions/51520/how-to-get-an-absolute-file-path-in-python/51523#51523
In [9]:
import os
os.path.abspath("c2_27.ipynb") # Файл из рабочей папки
Out[9]:
Пока не ясно, сколько однотипных проектов будет в одной папке. Может быть очень много, поскольку безопаснее "забирать файлы" небольшими порциями, дабы не забанили, как робота...
In []:
----Projects
!----Project auto
!----Nissan
!----Ford
!----2008
!----jan
!----man < 18
!----
!----
После того, как я нарисовал эту схему, стало ясно, что надо организовывать сквозной поиск в папке и подпапках по шаблону (имени файла). http://stackoverflow.com/questions/120656/directory-listing-in-python/120701#120701
In [18]:
#import os
dirnames =['C:\\Users\\kiss\\Documents\\IPython Notebooks\\web\\raw_to_csv\\fold_in']
for dirname, dirnames, filenames in os.walk('.'):
# print path to all subdirectories first.
for subdirname in dirnames:
print os.path.join(dirname, subdirname)
# print path to all filenames.
for filename in filenames:
print os.path.join(dirname, filename)
# Advanced usage:
# editing the 'dirnames' list will stop os.walk() from recursing into there.
if '.git' in dirnames:
# don't go into any .git directories.
dirnames.remove('.git')
Не понял, почему этот код гуляет (walk) по материнским папкам в дереве. Надо будет почитать...
Вот пример, который, вроде бы, именно то, что надо http://stackoverflow.com/questions/3207219/how-to-list-all-files-of-a-directory-in-python
In [25]:
#import os
def get_filepaths(directory):
"""This function will generate the file names in a directory
tree by walking the tree either top-down or bottom-up. For each
directory in the tree rooted at directory top (including top itself),
it yields a 3-tuple (dirpath, dirnames, filenames).
"""
file_paths = [] # List which will store all of the full filepaths.
# Walk the tree.
for root, directories, files in os.walk(directory):
for filename in files:
# Join the two strings in order to form the full filepath.
filepath = os.path.join(root, filename)
file_paths.append(filepath) # Add it to the list.
return file_paths # Self-explanatory.
# Run the above function and store its results in a variable.
full_file_paths = get_filepaths("C:\\Users\\kiss\\Documents\\IPython Notebooks\\web\\raw_to_csv")
In [26]:
full_file_paths
Out[26]:
The path I provided in the above function contained 3 files— two of them in the root directory, and another in a subfolder called "SUBFOLDER." You can now do things like:
print full_file_paths which will print the list:
['/Users/johnny/Desktop/TEST/file1.txt',
'/Users/johnny/Desktop/TEST/file2.txt',
'/Users/johnny/Desktop/TEST/SUBFOLDER/file3.dat']
If you'd like, you can open and read the contents, or focus only on files with the extension ".dat" like in the code below:
print full_file_paths which will print the list:
['/Users/johnny/Desktop/TEST/file1.txt',
'/Users/johnny/Desktop/TEST/file2.txt',
'/Users/johnny/Desktop/TEST/SUBFOLDER/file3.dat']
If you'd like, you can open and read the contents, or focus only on files with the extension ".dat" like in the code below:
In [27]:
for f in full_file_paths:
if f.endswith(".txt"):
print f
Итак, вариант наверху приемлемый, но не использует возможности маскирования..., хотя, может быть просто поискать? адо бы изучить подробнее матчасть.
А вот пример с другой библиотекой http://docs.python.org/2/library/glob.html
In [31]:
import glob
print glob.glob("C:\\Users\\kiss\\Documents\\IPython Notebooks\\web\\raw_to_csv\\*.txt")
# Пытаемся найти файл в подпапке: fold_in\222.txt
# C:\Users\kiss\Documents\IPython Notebooks\web\raw_to_csv\fold_in\222.txt
Модули: вот первый вариант для сквозного формирования списка файлов¶
Another way to do it using just the glob module. Just seed the rglob method with a starting base directory and a pattern to match and it will return a list of matching file names. http://stackoverflow.com/questions/2186525/use-a-glob-to-find-files-recursively-in-python/2186565#2186565
In [32]:
import glob
import os
def _getDirs(base):
return [x for x in glob.iglob(os.path.join( base, '*')) if os.path.isdir(x) ]
def rglob(base, pattern):
list = []
list.extend(glob.glob(os.path.join(base,pattern)))
dirs = _getDirs(base)
if len(dirs):
for d in dirs:
list.extend(rglob(os.path.join(base,d), pattern))
return list
In [36]:
rglob('C:\\Users\\kiss\\Documents\\IPython Notebooks\\web\\raw_to_csv','*.ipynb')
Out[36]:
Для начала подойдет - сквозной поиск по маске осуществляется простым вызовом функции rglob (base, pattern)... И пути полные... а сам пример выше...
Вот документация http://docs.python.org/2/library/glob.html, где есть примеры использования:
The glob module finds all the pathnames matching a specified pattern according to the rules used by the Unix shell. No tilde expansion is done, but *, ?, and character ranges expressed with [] will be correctly matched.
For a literal match, wrap the meta-characters in brackets. For example, '[?]' matches the character '?'.
Вот документация http://docs.python.org/2/library/glob.html, где есть примеры использования:
The glob module finds all the pathnames matching a specified pattern according to the rules used by the Unix shell. No tilde expansion is done, but *, ?, and character ranges expressed with [] will be correctly matched.
For a literal match, wrap the meta-characters in brackets. For example, '[?]' matches the character '?'.
Очевидно, что знак '?' можно испоьзовать для того, чтобы маскировать выбор по параметрам имени файла.
Посты чуть ниже также могут вас заинтересовать
Комментариев нет:
Отправить комментарий