基礎3 ファイル入出力・関数・応用

ファイルの読込

filename = "./sample.txt"  \\変数にファイルのパスを入れる

f = open(filename, mode = "r", encoding = "utf-8") \\open関数でファイルを開いて、読み取りモード

for i in f:   \\for i で繰り返す

    print(i)

 

\\これだと改行コードの影響で文字間が開いたものが表示される

2016 03 05

0       1.0

1       1.1

2       1.4

3       1.3

4       1.4

5       1.8

filename = "./sample.txt"  \\変数にファイルのパスを入れる

f = open(filename, mode = "r", encoding = "utf-8") \\open関数でファイルを開いて、読み取りモード

for i in f:

    print(i)

 

filename = "./sample.txt"

f = open(filename, mode = "r", encoding = "utf-8")

for i in f:

    k = i.strip()   \\.stripで改行コードを削除する

 

    print(k)
 \\普通の見た目で出力される

2016 03 05
0       1.0
1       1.1
2       1.4
3       1.3
4       1.4
5       1.8
 

\\値だけを抽出する

filename = "./sample.txt"

f = open(filename, mode = "r", encoding = "utf-8")

for i, j in enumerate(f):

    k = j.strip()

    if i > 0:       \\インデックスが0より大きい時だけ

        k2 = k.split("\t")   \\タブを取る

        print(k2[1])    \\インデックス1をプリント

 

out

1.0

1.1

1.4

1.3

1.4

1.8

 

ファイルの出力

\\カレントディレクトリにoutput.txtというファイルを作る

filename = "./output.txt"

f = open(filename, mode = "w",encoding = "utf-8")

\\Writeモードで エンコードはutf-8にする

 

\\forループで数字を10まで書く

for i in range(10):

    f.write(str(i)+"\n") \\文字列として書いて改行も入れる

 

f.close() \\f.closeで出力される

 

with

withを使うとf.closeしなくても自動的に出力してくれる。

 

\\カレントディレクトリのsample.txtをReadモードで開く

with open("./sample.txt", mode = "r",encording ="utf-8") as f:

    for i in f:

        print(i)

\\これだけでf.closeしなくても出力してくれる

 

 

関数の定義

\\def で関数を定義する

 

def distance(x,y,z):   \\わかりやすい関数名をつけ、引数を定義

    dis = (x**2 + y**2 + z**2)**0.5  \\変数で処理する

    return dis       \\戻り値

 

distance(3.0, 1.0, 2.0)  \\インプットする

 

out 3.7416573867739413  \\計算される

 

変数のスコープ

【グローバル変数】:誰でもアクセスできる変数

【ローカル変数】:関数の中で定義されている変数。勝手に変更されたくないものはこれを使う。

 

x = 3.0

 

def func1():   \\引数をとらない

    print(x)

    return  \\戻り値もとらない

 

func1()

out 3.0   \\関数の外で定義した変数を返す

 

def func2(x):   \\引数をとる

    y = 1.0    \\関数の中で変数を定義

    return(x + y)  \\内と外の足し算という戻り値

 

 

func2(x)

out 4.0   \\成功

    \\変数yを見ようとしても見れない

 

 

デフォルト引数

引数に値を与えない場合に利用されるデフォルト値を設定することができる。

 

def distance(x=1.0,y=2.0,z=3.0):  \\関数を定義する際に引数にデフォルト値を入れる

    dis = (x**2 + y**2 + z**2)**0.5  \\変数で処理する

    return dis

 

distance()           \\引数を与えないと

out 3.7416573867739413    \\デフォルト値で計算される

 

distance(3.0)         \\1つだけ引数を与えると、

out 4.69041575982343    \\xに代入されて計算される

 

無名関数(ラムダ式)

\\通常の関数はこのように3行必要になるが、ラムダ式を使うと1行で済む

def distance(x=1.0,y=2.0,z=3.0):

    dis = (x**2 + y**2 + z**2)**0.5

    return dis

 

f = lambda x,y,z: (x**2 + y**2 + z**2)**0.5 \\この1行で終わり。関数名がない

 

f(1.0,2.0,3.0)          \\この変数に値を与えると

out 3.7416573867739413      \\計算される

 

map と filter

ラムダ式は、mapとfilterでさらに便利に使うことができる

◆map は関数をリストの値すべてにまとめて作用させることができる

 

num_list = [1,2,3,4,5,6,7,8] \\リストを定義

 

func = lambda x : x**2   \\値を二乗するラムダ関数を定義

 

func(3.0)         \\通常の使い方ならこのように

out 9.0         \\二乗された値が1つ返ってくる

 

\\funcという関数をnum_list全体に作用させる

list(map(func, num_list))     \\その結果をリストに入れる

out [1, 4, 9, 16, 25, 36, 49, 64]

 

 

◆filter は条件に合致した値だけをフィルタリングすることができる。

 

fileList = ["aaa.txt", "bbb.csv", "ccc.xlsx"]  \\ファイル名のリストを作る

 

func2 = lambda x : x[-4:] == ".txt"  \\拡張子が.txtのものを示す関数を作る

 

list(filter(func2, fileList))   \\func2というフィルターをfileListにかけて

out ['aaa.txt']        \\テキストファイルを抽出

 

モジュール

モジュールとは、関数のかたまり。自分で関数を定義しなくても

既に誰かが作っているので、それを活用する。

 

モジュールのインポート

import numpy  \\numpyというモジュールをインポートする

 

numpy.abs(-3.0)  \\numpyが持つ多くの関数が使えるようになった

out 3.0         \\ここでは絶対値を返すabs関数

 

numpy.random.rand()    \\こちらは乱数を返すrandom関数

out 0.04398319152430852  \\引数を入れないと0~1までの乱数を返す

 

import numpy as np   \\おすすめはこの方法でのインポート

np.abs(-4.0)    \\numpyと記述する代わりにnpと短くできる

out 4.0

 

OSモジュール

import os     \\OSモジュールをインポートする

 

os.getcwd()     \\Current Work DirectoryをGetする

out 'C:\\Users\\khaku'

 

c_path = os.getcwd()  \\それをc_pathという変数に入れる

 

os.listdir(c_path)    \\カレントディレクトリのディレクトリリストを作成

 

リスト内包表記

通常の表記でリストの要素を二乗すると

num_list = []           \\空のリストを作り

for i in range(11):       \\forループで0から10までをiに格納し

    num_list.append(i**2)       \\リストに要素を付加する(変数を二乗しながら)

num_list                \\出力 

out:[0, 1, 4, 9, 16, 25, 36, 49, 64, 81, 100]   \\0~10までが二乗されている

 

リスト内包表記を使うと

num_list2 = [i**2 for i in range(11)]         \\二乗する処理とforループが1行で記載できる

num_list2

out:[0, 1, 4, 9, 16, 25, 36, 49, 64, 81, 100]   \\出力すると同じ結果となる。

 

テキストファイルだけ取り出す処理

import os         \\OSモジュールをインポートする

filelist = os.listdir()     \\カレントディレクトリのディレクトリリストを作成

filelist            \\これだとすべてのファイルリストが表示される

 

txtlist = [i for i in filelist if i[-4:]==".txt"]  \\拡張子.txtのファイルだけを抽出

txtlist

out:['test.txt']                  \\あれば出力される

 

正規表現

if文だけではできないような複雑な抽出を可能にする

 

import re              \\最初にreをインポート

print("a\tb\tc")    \\このように記述すると\tが効いて

a b c     \\このように出力されるが、

 

print(r"a\tb\tc")       \\raw stringを示すrを記述することで

out:a\tb\tc     \\そのまま表示される

 

re.search(r"123", "123456")     \\123という文字列を123456から探す方法

out:<re.Match object; span=(0, 3), match='123'>  \\あったらこのように返す


m = re.search(r"123", "123456")   \\それを変数mに代入する

m.start()             \\その文字列のスタート位置を聞く

out:0                \\一番最初と

m.end()              \\その文字列の終わる位置を聞く

out:3

 

re.search(r"1*", "1111111")      \\ワイルドカードも使える

out:<re.Match object; span=(0, 7), match='1111111'>

 

re.search(r"1*", "1")         \\ワイルドカードも使える

out:<re.Match object; span=(0, 1), match='1'>

 

re.search(r"1\s23", "1 23")      \\ \sは半角スペースを意味する

out:<re.Match object; span=(0, 4), match='1 23'>

 

re.search(r"^123", "abc123")   #^は文頭にあるかを確認している

              #outが返ってこないのでマッチしてない

re.search(r"123$", "abc123")   #$は文末にあるかを確認している

out:<re.Match object; span=(3, 6), match='123'>

 

re.search(r"[123]456", "2456")  #[]内のいずれかとその後の文字列を探す

out:<re.Match object; span=(0, 4), match='2456'>

 

re.search(r"Python3?","Python")   #?の1つ前の文字があるかないか不明な場合

out:<re.Match object; span=(0, 6), match='Python'>   #0回でしたがマッチ

 

re.search(r"Python\d" , "Python2")   #\dは数字1文字

out:<re.Match object; span=(0, 7), match='Python2'>

 

re.search(r"(red|blue)", "I like red")    #丸カッコとパイプで複数の文字列を探せる

out:<re.Match object; span=(7, 10), match='red'>

 

正規表現(実践編)

import re                                               \\最初にreをインポート

 

obj = "3.01E-10 1.000123 1.051E1 NaN"     \\変数にスペース区切りで4種類のデータを入れる

                   \\それを様々な方法で抽出する

 \\リストとして抽出するにはre.searchではなく、re.findallを使う

re.findall(r"-?\d\.", obj)     \\正負どちらでもいいように「-?」 1文字の数字「\d」

               \\その後ピリオド「\.」

out:['3.', '1.', '1.']

 

re.findall(r"-?\d\.\d*", obj)     \\さらに複数桁の数字を追加「\d*」

out:['3.01', '1.000123', '1.051']

 

re.findall(r"-?\d\.\d*E?-?\d?\d?", obj)  \\Eがあってもなくても「E?」

                  \\-があってもななくても「-?」

                  \\続いて数字が1桁または2桁「\d?\d?」

out:['3.01E-10', '1.000123', '1.051E1']  \\これで数字は完全に抽出できた

 

re.findall(r"(-?\d\.\d*E?-?\d?\d?|NaN)", obj) \\NaNは()内に入れて、|で分けて記載

out:['3.01E-10', '1.000123', '1.051E1', 'NaN'] \\これですべて抽出できた