Python OSモジュール入門

このチュートリアルでは、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']


見ての通り、DataPopulation_Dataという2つのフォルダがあります。また、3つのファイルがあります。マークダウンファイルの README.md と、2つのPythonファイル、 tutorial.pytutorial_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つのサブディレクトリができました。testdirlevel1dirです。level1dirの下には、level2dirというディレクトリがあります。

単一および複数のディレクトリを再帰的に削除する

os` モジュールには、ディレクトリを変更したり削除したりするためのメソッドも用意されています。

では、rmdir を使って、先ほど作成したディレクトリを削除してみましょう。

os.rmdir('testdir')


カレントディレクトリツリーをチェックして、そのディレクトリがもう存在しないことを確認します。

list_files(os.getcwd())


出力します。

New York/
    New York_population.csv
    level1dir/
        level2dir/


ご覧の通り、testdirが削除されました。

試しに、入れ子になっている level1dirlevel2dir のディレクトリ構造を削除してみましょう。

os.rmdir('level1dir')


出力してみましょう。

OSError
Traceback (most recent call last)
<ipython-input-14-690e535bcf2c in <module()
----&gt; 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にはもっと多くの機能があり、開発者の必要性に応じてもっと複雑なロジックを構築できることです。

タイトルとURLをコピーしました