このチュートリアルでは、Pythonの os
モジュールと一緒に作業する方法を学びます。
Pythonは、データ処理、データ解析、Webサイト構築など、様々な作業で近年最も頻繁に使用されている言語の1つです。その中で、OS に依存する様々なタスクが存在する。Pythonでは、Pythonモジュール os
を用いて、OSに依存したいくつかの機能を利用することができる。このパッケージはプラットフォームの機能を抽象化し、ファイルやフォルダの移動、作成、削除、変更を行うためのPython関数を提供します。このチュートリアルでは、このパッケージのインポート方法、基本的な機能、そしてこのライブラリを使用してデータマージタスクを行うPythonのサンプルプロジェクトについて学習します。
いくつかの基本的な機能
いくつかのサンプルコードで、このモジュールを調べてみましょう。
ライブラリをインポートする。
import os
このモジュールで使用できるメソッドのリストを取得しましょう。
print(dir(os))
出力してみましょう。
['DirEntry', 'F_OK', 'MutableMapping', 'O_APPEND', 'O_BINARY', 'O_CREAT', 'O_EXCL', 'O_NOINHERIT', 'O_RANDOM', 'O_RDONLY', 'O_RDWR', 'O_SEQUENTIAL', 'O_SHORT_LIVED', 'O_TEMPORARY', 'O_TEXT', 'O_TRUNC', 'O_WRONLY', 'P_DETACH', 'P_NOWAIT', 'P_NOWAITO', 'P_OVERLAY', 'P_WAIT', 'PathLike', 'R_OK', 'SEEK_CUR', 'SEEK_END', 'SEEK_SET', 'TMP_MAX', 'W_OK', 'X_OK', '_Environ', '__all__', '__builtins__', '__cached__', '__doc__', '__file__', '__loader__', '__name__', '__package__', '__spec__', '_execvpe', '_exists', '_exit', '_fspath', '_get_exports_list', '_putenv', '_unsetenv', '_wrap_close', 'abc', 'abort', 'access', 'altsep', 'chdir', 'chmod', 'close', 'closerange', 'cpu_count', 'curdir', 'defpath', 'device_encoding', 'devnull', 'dup', 'dup2', 'environ', 'errno', 'error', 'execl', 'execle', 'execlp', 'execlpe', 'execv', 'execve', 'execvp', 'execvpe', 'extsep', 'fdopen', 'fsdecode', 'fsencode', 'fspath', 'fstat', 'fsync', 'ftruncate', 'get_exec_path', 'get_handle_inheritable', 'get_inheritable', 'get_terminal_size', 'getcwd', 'getcwdb', 'getenv', 'getlogin', 'getpid', 'getppid', 'isatty', 'kill', 'linesep', 'link', 'listdir', 'lseek', 'lstat', 'makedirs', 'mkdir', 'name', 'open', 'pardir', 'path', 'pathsep', 'pipe', 'popen', 'putenv', 'read', 'readlink', 'remove', 'removedirs', 'rename', 'renames', 'replace', 'rmdir', 'scandir', 'sep', 'set_handle_inheritable', 'set_inheritable', 'spawnl', 'spawnle', 'spawnv', 'spawnve', 'st', 'startfile', 'stat', 'stat_float_times', 'stat_result', 'statvfs_result', 'strerror', 'supports_bytes_environ', 'supports_dir_fd', 'supports_effective_ids', 'supports_fd', 'supports_follow_symlinks', 'symlink', 'sys', 'system', 'terminal_size', 'times', 'times_result', 'truncate', 'umask', 'uname_result', 'unlink', 'urandom', 'utime', 'waitpid', 'walk', 'write']
さて、getcwd
メソッドを使うと、現在の作業ディレクトリのパスを取得することができます。
print(os.getcwd())
出力
C:UsershpandyaOneDriveworkStackAbuseos_pythonos_pythonProject
フォルダーとファイルの一覧
listdir`を使って、カレントディレクトリにあるフォルダやファイルをリストアップしてみましょう。
print(os.listdir())
出力されます。
['Data', 'Population_Data', 'README.md', 'tutorial.py', 'tutorial_v2.py']
見ての通り、Data
とPopulation_Data
という2つのフォルダがあります。また、3つのファイルがあります。マークダウンファイルの README.md
と、2つのPythonファイル、 tutorial.py
と tutorial_v2.py
です。
プロジェクトフォルダ全体のツリー構造を取得するために、関数を書いて、 os.walk()
を使って、カレントディレクトリの各フォルダにあるすべてのファイルを繰り返し検索してみましょう。
# function to list files in each folder of the current working directory
def list_files(startpath):
for root, dirs, files in os.walk(startpath):
# print(dirs)
if dir!= '.git':
level = root.replace(startpath, '').count(os.sep)
indent = ' ' * 4 * (level)
print('{}{}/'.format(indent, os.path.basename(root)))
subindent = ' ' * 4 * (level + 1)
for f in files:
print('{}{}'.format(subindent, f))
この関数は現在の作業ディレクトリのパスで呼び出します。
startpath = os.getcwd()
list_files(startpath)
出力します。
Project/
README.md
tutorial.py
tutorial_v2.py
Data/
uscitiesv1.4.csv
Population_Data/
Alabama/
Alabama_population.csv
Alaska/
Alaska_population.csv
Arizona/
Arizona_population.csv
Arkansas/
Arkansas_population.csv
California/
California_population.csv
Colorado/
Colorado_population.csv
Connecticut/
Connecticut_population.csv
Delaware/
Delaware_population.csv
...
注:出力は簡潔にするために切り捨てられています。
出力からわかるように、フォルダの名前は /
で終わっており、フォルダ内のファイルは右にスペース4つ分インデントされています。Dataフォルダには
uscitiesv1.4.csvという名前の csv ファイルが 1 つあります。このファイルには、アメリカ合衆国の各都市の人口に関するデータが含まれています。Population_Data
フォルダにはState用のフォルダがあり、uscitiesv1.4.csv
から抽出した各州の人口データをcsvファイルに分けて格納している。
作業ディレクトリの変更
作業ディレクトリを変更して、「New York」という州のデータのディレクトリに入りましょう。
os.chdir('Population_Data/New York')
ここで、このディレクトリで再び list_files
メソッドを実行してみましょう。
list_files(os.getcwd())
出力されます。
New York/
New York_population.csv
このように、Population_Data
フォルダーの下にNew York
フォルダーが入力されていることがわかります。
単一および入れ子のディレクトリ構造の作成
では、このディレクトリの中に testdir
という新しいディレクトリを作りましょう。
os.mkdir('testdir')
list_files(os.getcwd())
出力します。
New York/
New York_population.csv
testdir/
見ての通り、現在の作業ディレクトリの中に新しいディレクトリが作成されます。
2階層でネストしたディレクトリを作成してみましょう。
os.mkdir('level1dir/level2dir')
出力してください。
Traceback (most recent call last):
File "<ipython-input-12-ac5055572301", line 1, in <module
os.mkdir('level1dir/level2dir')
FileNotFoundError: [WinError 3] The system cannot find the path specified: 'level1dir/level2dir'
Errorが発生しました。具体的には、FileNotFoundError
が発生します。なぜ、ディレクトリを作成しようとしているときに FileNotFound
というエラーが発生するのか、不思議に思うかもしれません。
Pythonモジュールは、ディレクトリ level2dir
を作成するために、level1dir
というディレクトリを探しているからです。そもそも level1dir
が存在しないので、 FileNotFoundError
を投げてしまいます。
このような目的のためには、再帰的に複数のディレクトリを作成できる mkdirs()
関数が代わりに使用されます。
os.makedirs('level1dir/level2dir')
現在のディレクトリツリーをチェックします。
list_files(os.getcwd())
出力します。
New York/
New York_population.csv
level1dir/
level2dir/
testdir/
見ての通り、New York
フォルダの下に2つのサブディレクトリができました。testdirと
level1dirです。level1dir
の下には、level2dir
というディレクトリがあります。
単一および複数のディレクトリを再帰的に削除する
os` モジュールには、ディレクトリを変更したり削除したりするためのメソッドも用意されています。
では、rmdir
を使って、先ほど作成したディレクトリを削除してみましょう。
os.rmdir('testdir')
カレントディレクトリツリーをチェックして、そのディレクトリがもう存在しないことを確認します。
list_files(os.getcwd())
出力します。
New York/
New York_population.csv
level1dir/
level2dir/
ご覧の通り、testdir
が削除されました。
試しに、入れ子になっている level1dir
と level2dir
のディレクトリ構造を削除してみましょう。
os.rmdir('level1dir')
出力してみましょう。
OSError
Traceback (most recent call last)
<ipython-input-14-690e535bcf2c in <module()
----> 1 os.rmdir('level1dir')
OSError: [WinError 145] The directory is not empty: 'level1dir'
見ての通り、これは OSError
を投げますが、その通りです。これは、level1dir
ディレクトリが空でないと言っています。その下には level2dir
があるので、これは正しいです。
rmdir` メソッドでは、Unix のコマンドライン版と同じように、空でないディレクトリを削除することはできません。
makedirs()メソッドと同じように、ツリー構造になっているディレクトリを再帰的に削除する
rmdirs()` メソッドも試してみましょう。
os.removedirs('level1dir/level2dir')
ディレクトリのツリー構造をもう一度見てみましょう。
list_files(os.getcwd())
出力します。
New York/
New York_population.csv
これで、以前のディレクトリの状態に戻りました。
データ処理による例
これまで、ネストされたディレクトリ構造を表示、作成、削除する方法について検討してきました。では、os
モジュールがどのようにデータ処理に役立つのか、その例を見てみましょう。
そのために、ディレクトリ構造を1つ上の階層に移動してみましょう。
os.chdir('../')
これで、再びディレクトリツリー構造を表示してみましょう。
list_files(os.getcwd())
出力します。
Population_Data/
Alabama/
Alabama_population.csv
Alaska/
Alaska_population.csv
Arizona/
Arizona_population.csv
Arkansas/
Arkansas_population.csv
California/
California_population.csv
Colorado/
Colorado_population.csv
Connecticut/
Connecticut_population.csv
Delaware/
Delaware_population.csv
...
注:出力は簡潔にするために切り捨てられている。
各州のディレクトリを繰り返し、同様にCSVファイルをマージして、全州のデータをマージしてみましょう。
import os
import pandas as pd
# create a list to hold the data from each state
list_states = []
# iteratively loop over all the folders and add their data to the list
for root, dirs, files in os.walk(os.getcwd()):
if files:
list_states.append(pd.read_csv(root+'/'+files[0], index_col=None))
# merge the dataframes into a single dataframe using Pandas library
merge_data = pd.concat(list_states[1:], sort=False)
osモジュールのおかげで、各州の人口データを含むデータフレームである
merge_data` を作成することができました。
結論
この記事では、Pythonの組み込みモジュールである os
のさまざまな機能について簡単に説明しました。また、データサイエンスとアナリティクスの世界でこのモジュールがどのように使用されるかの簡単な例も見ました。重要なのは、os
にはもっと多くの機能があり、開発者の必要性に応じてもっと複雑なロジックを構築できることです。