## 1からnまでのリストを作る list(range(1,n+1)) ## a ~ b の間でランダムな整数を n個 リスト化する import random [random.randint(a,b) for _ in range(n)] ## 0 ~ 1 の間でランダムな浮動小数点を n個 リスト化する import random [random.random() for _ in range(n)]
SIGNATE Cloud Python入門
s1 = "Data Science Training" s2 = s1.split() # デフォルトで空白区切で文字列をリスト化してくれる ['Data', 'Science', 'Training'] s3 = ",".join(s2) Data,Science,Training s1.replace(" ", "", 回数) # 文字列の置換 ▲リスト型には使えない▼ # リストの場合は s1[0]= などで上書きして直す s1.strip("Ding") # 文字列の両端から該当文字を削除 データクレンジングに有効かも s1.lstrip("Da") # 左端から該当文字を削除 s1.rstrip("raining") # 右端から該当文字を削除 print("a" in s1) # True/Falseで返ってくる s1.find("a") # インデックス番号で返ってくる ▲リスト型には使えない▼ s1.index("a") # リスト用 s1.count("a") # 個数が返ってくる len(s1) # 文字列の長さ(空白もカウントされる) s1.isdecimal() # 十進数だけ? True/Falseで返ってくる s1.isdigit() # 数字だけ? s1.isnumeric() # 数を表す文字だけ? ほぼ同じみたいだが・・ s1.isalpha() # アルファベット/ひらがな/カタカナ/漢字だけ? s1.isalnum() # 上記全てに該当する? s1.isascii() # ASCII文字だけ? s1.bool() # ブーリアン判定 リスト用 len(lst) # リストの要素数を返す max(lst) # リストの最大値を返す min(lst) # リストの最小値を返す sum(lst) # リストの全要素を足す lst.index("a") # リストでインデックス番号を返すにはこれ lst.append(追加要素) # 一番後ろに追加する lst += 追加要素 でもいける lst.insert(インデックス番号, 追加要素) # 指定したインデックス番号に差し込む del s1[3:6] # 3番目から5番目の要素をリストから削除する 特殊な形だねぇ・・ lst.remove("要素") # 要素そのものをリストから削除する lst.sort() # 昇順に並べ替える ▼print()の中に入れるとNoneになる。sort()実施後に別口でprint()すること。 lst.sort(reverse=True) # 降順に並べ替える ▼print()の中に入れるとNoneになる。sort()実施後に別口でprint()すること。 辞書用 for key in dict.keys(): # 辞書からkeyを取り出してループを回す keys() for value in dict.values(): # 辞書からvalueを取り出してループを回す values() for key,value in dict.items(): # 辞書からkeyとvalueを取り出してループを回す items() 重複をなくした降順リストにする a = [6, 10, 8, 10, 6, 8] a = sorted(list(set(a)), reverse=True) # set()関数は{dict}が返ってきてしまうので、list()でリストに戻して、最後に降順ソート
# リストからindex番号と値を取り出す for index,value in enumerate(list): # 辞書からindex番号と値を取り出す for key,value in dict.items(): # 0から4までの数字を2乗したリストの変数squareを、内包表記で作成しましょう square = [i**2 for i in range(5)] print(square) # 0から9までの数字で3で割り切れない数のリストの変数non_triを、内包表記で作成しましょう non_tri = [i for i in range(10) if i%3!=0 ] print(non_tri) # リストから辞書を作る vegetables = ['tomato','cabbage','onion','carrot','cucumber'] vegetables_dict = {e:len(e) for e in vegetables}
変数 = open('Sample.txt','r') # 読み込みモード 変数 = open('Sample.txt','w') # 書き込みモード open_file = open('Sample.csv','r') # 読み込みモードでファイルを開く open_file = open('Sample.csv','w') # 書き込みモードでファイルを開く print(open_file.closed) # ファイルが閉じられているか否か True/False read_file = open_file.read() # ファイルを全て文字列として読み込む read_file = open_file.readline() # ファイルを1行だけ文字列として読み込む read_file = open_file.readlines() # ファイルを全てリストとして読み込む data = 'id,name,score' # 書き込みたいデータ list_data = ['id', ',', 'name', ',', 'score'] # 書き込みたいデータ open_file.write(data) # ファイルにデータを書き込む open_file.writelines(list_datadata) # ファイルにデータを書き込む open_file.close() # ファイルを閉じる print(open_file.closed) # ファイルが閉じられているか否か True/False with open("data.csv") as open_file: # with構文を使用してファイルを開く print(open_file.closed) # ファイルが閉じているかを確認する read_file = open_file.read() # 開いたファイルを読み込む print(read_file) print(open_file.closed) # ファイルが閉じているかを確認する
## グラフ描画 df.列名.value_counts().plot(kind="bar") # 要素のユニーク数を棒グラフで表現
Python 機械学習
## データフレーム全体の操作 import pandas as pd import matplotlib.pyplot as plt %matplotlib inline # plt.show()を省略してもグラフが出力される & 2つ以上のグラフを同時に出力できる # csvファイルの読み込み pd.read_csv("path.csv", nrows=num, encoding="shift-jis", usecols=["列名1","列名2","列名3"], dtype="str", dtype={"列名":"タイプ"}) # tsvファイルの読み込み pd.read_csv("path.tsv", sep="\t") # Excelファイルの読み込み pd.read_excel("path.xlsx") # データフレームの作成 pd.DataFrame( { "列名": [1,2,3,4] } ) # データフレームを作成する時は、辞書型で書く { "列名":[リスト] } # データフレームの縦結合 pd.concat([df1, df2]) # CONCATnate デフォルトで 縦 に連結 pd.concat([df1, df2], axis=1) # 横 に連結 # データフレームの横結合 pd.merge(df1, df2, on="結合キー列", how="inner") # how=inner 内部結合 / outer 完全外部 / left 左外部 / right 右外部
## 行・列の操作 # カラム名の変更 df.rename(columns={"現カラム名":"新カラム名"}) # 外れ値を含む列 df.列名.clip(lower=引数, upper=引数) # 下限と上限を決めて外れ値を収める どちらか片方でも可 # 欠損値を含む行 df.isnull().any() # 欠損値が存在するかを確認 df.isnull().sum() # 欠損値の個数を確認 df.列名.fillna(df.列名.mode()[0]) # 最頻値で埋める df.dropna() # 欠損値を含む行を削除 df.dropna(subset="列名") # 指定した列に欠損値を含む行を削除 df.dropna(subset=["列名1", "列名2"]) # 複数列を指定して、いずれかに欠損値を含む場合は行削除 df.drop_duplicates(subset=["列名1", "列名2", "列名3"]) # 重複行を削除 ※subsetに書いた列で重複判定して削除する df.drop_duplicates(keep="last") # 最後のレコードを残して削除 df.drop_duplicates(keep="False") # 重複しているものは1行たりとも残さず全て削除
## レコードの絞り込み > < より大きい / 未満(より小さい) >= <= 以上 / 以下 & かつ | または ※ and とか or とか not は使えない★ ~ でない(反転) # 単一条件に合ったレコードを抽出 df[df.列名 == num] # 数値とが等しいレコードを抽出★ df[df.列名 == "str"] # 文字列と等しいレコードを抽出★ df.query("列名 == num") # strの場合は'シングル'クォーテーションで括る★ df.列名[df.列名 != num] # 値と等しくないレコードを抽出 df.query("列名 != 'str'") # strの場合はシングルクォーテーションで括る # 複数条件に合ったレコードを抽出 df[(df["列名1"]=="str") & (df["列名2"]>=num)] # 1つ1つの条件文を、丸括弧 ( ) で囲むのを忘れずに★ df.query("列名1 == 'str' & 列名2 > num") # and strの場合はシングルクォーテーションで括る df.query("列名1 != 'str' | 列名2 > num") # or strの場合はシングルクォーテーションで括る # str.contains()メソッドを使用したレコード抽出 df[df.列名.str.contains("〇〇")] # リストの中身はTrue/Falseが返っている df[df.列名.str.contains("\(株\)")] # (株) のように半角カッコを含む場合は、直前に \ を置いてメタ文字エスケープ # 日付の範囲でレコード抽出 import datetime # datetime64[ns]タイプの[date]列から抽出する例 df.query("datetime.datetime(2024,7,1) < date < datetime.datetime(2024,8,31)") # 指定した期間 # [y]列が数値だったら df.query("y < datetime.datetime.now().year") # 去年までのもの # 列名1でグルーピングして、列名2で集計 df.groupby("列名1")["列名2"].mean().reset_index(drop=True/False) # 平均値だけ # 旧indexをdropする/しない df.groupby("列名1")["列名2"].agg(["mean","median"]).reset_index() # 平均値と中央値 # 列名1と列名2でグルーピングして、列名3で集計 df.groupby(["列名1","列名2"])["列名3"].mean().reset_index() # 複数項目のクロス集計 # 列名1でグルーピングして、列名2と列名3で違う集計を行う df.groupby("列名1").agg({"列名2":"mean", "列名3":"median"}).reset_index() # 固定長文字列の抽出 ★ 0 スタートなので注意 df.列名.apply(lambda x: x[0]) # 先頭文字を抽出 df.列名.apply(lambda x: x[-1]) # 末尾文字(右から1文字目)を抽出 df.列名.apply(lambda x: x[3:5]) # 4文字目と5文字目を抽出 df.列名.apply(lambda x: x[:3] # 先頭から3文字目まで抽出 df.列名.apply(lambda x: x[3:] # 4文字目から最後まで抽出 # 可変長文字列の抽出 指定文字で左右に分割してリスト化し、要素として抽出することで実現 df.列名.apply(lambda x: x.split(", ")[2]) # ', 'で区切った3番目の文字列を抽出 df.列名.apply(lambda x: x.split(" ")[1]) # 半角空白の後ろの文字列を抽出 df.列名.apply(lambda x: x.split("@")[0]) # メアドからユーザ名を抽出 df.列名.apply(lambda x: x.split("@")[1]) # メアドからドメイン名を抽出
## データの集計 df.shape # 行列数 df.size # データサイズ(欠損値を含むデータの個数) df.列名.nunique() # ユニーク数 df.列名.unique() # ユニークな要素の一覧 df.sort_values(by="列名", na_positon="first/last", ascending=True) # 単一カラム df.sort_values(by=["列名1","列名2"], ascending=[True,False]) # 複数カラム df.列名.value_counts(ascending=True) # 要素別の頻度(出現回数)と昇順True, 降順False df.列名.value_counts(normalize=True) # 割合として表示(出現回数を正規化してる) df.列名.value_counts().sort_values(ascending=True) df.列名.sum() # 合計値 df.列名.mean() # 平均 と★ df.列名.std() # 標準偏差 を並べて表示すると、68%範囲の目星がつく★ df.列名.median() # 中央値 df.列名.mode()[0] # 最頻値 df.列名.min() # 最小値 df.列名.max() # 最大値 print(df.列名.max() - df.列名.min()) # データの範囲も見てみよう print((df.列名1.mean() - df.列名2.mean()) *100 - 100) # 平均値の変化率[%]▲ df.groupby.列名.sum() # グルーピングして合計を算出 df.groupby.列名.mean() # グルーピングして平均を算出 df.pivot_table(index="列名1", columns="列名2", values="計算対象の列名", aggfunc="sum") # 合計値のクロス集計★ df.pivot_table(index="列名1", columns="列名2", values="計算対象の列名", aggfunc="mean") # 平均値のクロス集計★ df.corr() # 相関係数(-1~+1) # これだけでは不十分で、★ ※df.plot.scatter(x="列名1", y="列名2") # 散布図を併用しないと重要な相関を見逃す★ # ランキング df.列名.rank(ascending=False/True, method="min/max") # False 降順 / True 昇順 # method= min(最小値が順位となる) / max(最大値が順位となる) / デフォルトは average(平均が順位となる) dense(最小値が順位となり、後続の順位を詰める)
## 描画 df.列名.hist() # ヒストグラムで分布をみる df.列名.plot(kind="hist") df.列名.plot.box() # 箱ひげ図で分布を見る df.列名.plot(kind="box") ※df.corr() # 相関係数(-1~+1) # これだけでは不十分で、★ df.plot.scatter(x="列名1", y="列名2") # 散布図を併用しないと重要な相関を見逃す★ plt.show() # 描画
## 正規表現 import re ^ 先頭 $ 末尾 . 任意の1文字 ? 0回または1回 不特定の1文字 * 0回以上の繰り返し 不特定の複数文字 + 1回以上の繰り返し # 抽出 re.search("抽出したい文字列パターン", "対象文字列").group() # groupで結果の取り出し 使い方わかんねぇぇ df.query("列名.str.contains('^J.*A$', regex=True)", engine="python") # Jから始まりAで終わるもの df.query("列名.str.contains('[6-8]$', regex=True)", engine="python") # 6,7,8のいずれかで終わるもの # 置換 re.sub("置換したい文字列パターン", "置換後の文字列", 置換対象) 使い方例 df.列名.apply(lambda x: re.sub("※.*", "", x)) # ※以降の文字列を全て消し去る
## 文字列操作 ★ df["new"] = で、新たな列に結果を出力した方がいいかもね # 文字列の結合 df.列名1 + df.列名2 df.apply(lambda x: x.列名1 + x.列名2, axis=1) df.apply(lambda x: x[列名1] + x[列名2], axis=1) # 文字列の置換 df.列名.map({"置換前":"置換後"}) df.列名.replace({"置換前":"置換後"}) # 文字列の置換・消去 df.列名.apply(lambda x: x.replace("置換対象文字列", "置換後の文字列")) あるある df.社名.apply(lambda x: x.replace("(株)", "株式会社")) (株)を株式会社に置換 df.電話番号.apply(lambda x: x.replace("-", "")) ハイフンを消す # nanに置換 import math import numpy as np df.loc["インデックス名", "列名"] = math.nan | np.nan # 大文字・小文字揃え df.列名.apply(lambda x: x.upper()) df.列名.apply(lambda x: x.lower()) # 半角・全角揃え import mojimoji df.列名.apply(lambda x: mojimoji.han_to_zen(x)) # 半角→全角 df.列名.apply(lambda x: mojimoji.zen_to_han(x)) # 全角→半角 # ビニング df["bin"] = pd.cut(df.列名, bins=["区切1","区切2","区切3","区切4"], right=False, labels=["Aランク","Bランク","Cランク"]) # right=False/Trueエッジをどちらに含めるか False 20 <= value < 30 True 20 < value <= 30 確認 df.bin.value_counts() # bin列でカウントして数が多い順に表示 df.bin.mode()[0] # 最頻値だけを表示 # インデックスの振りなおし df.reset_index(drop=True) # drop=Trueにすると、元のインデックス列を削除
# 日付型への変換 ★ df["new"] = で、新たな列に結果を出力した方がいいかもね import pandas as pd pd.to_datetime(df.列名) pd.to_datetime(df.列名, format="%Y年%m月%d日") 例 df["今日"] = "8月7日2024年" # 新たな列を作って df["今日"] = pd.to_datetime(df["今日"], format="%m月%d日%Y年") # ↑ df["今日"] = pd.to_datetime("2024/8/7") # てか1行で書ける # 日付型から要素を抜き出す ★ df["new"] = で、新たな列に結果を出力した方がいいかもね x.year:年 x.month:月 x.day:日 x.hour:時 x.minute:分 x.second:秒 x.weekday_name:曜日 例 df['年'] = df.生年月日.apply(lambda x: x.year) df['月'] = df.生年月日.apply(lambda x: x.month) df['日'] = df.生年月日.apply(lambda x: x.day) df[["年","月","日"]] # 日付型から差分を知る df['今日'] = pd.to_datetime('2024/8/7') df['経過日数'] = df.apply(lambda x: (x['今日']-x['生年月日']).days, axis=1) ▲後でちゃんと調べる df['年齢'] = df['経過日数']//365 # 切り捨て除算
モジュール
FizzBuzzナベアツ風
for i in range(1,41): if i%3 == 0 or 3 in list(map(int,str(i))): print(i,"(アホ)") else: print(i) >・・・ [8] [9] [1, 0] [1, 1] ・・・
完全数を求める
%%time # 自分を含まない約数の総和を求める関数 def divisors(n): div = [] for i in range(1,n): if n%i==0: div.append(i) if sum(div)==n: return sum(div) n = int(input()) print(f'{n} までの間に完全数があるか計算中…') # 1~nの間で、完全数があるかを求める for i in range(1,n+1): if divisors(i)==i: print(i) >10000 までの間に完全数があるか計算中… 6 28 496 8128 CPU times: total: 891 ms Wall time: 4.1 s
文字列操作
数値→リスト変換 一桁ずつstrとして分割し、intに変換してリストに格納
n = 123456789 lst = [int(x) for x in list(str(n))] print(lst) # [1, 2, 3, 4, 5, 6, 7, 8, 9]
リスト→数値変換 リストの要素を一つずつstrとして取り出して繋いで、intに変換
lst = [1, 2, 3, 4, 5, 6, 7, 8, 9] from functools import reduce # reduceモジュールの読み込みが必要 result = int(reduce(lambda x, y: x + y, [str(x) for x in lst])) # reduceで文字列+文字列を畳み込んでいく print(result) # 123456789
転じてリスト結合にも使える
lst1 = [1, 2, 3, 4, 5] lst2 = [6, 7, 8, 9, 10] result = reduce(lambda x, y: x + y, [lst1, lst2]) print(result) # [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
高階関数
ポイントは、関数を渡す際に () が無いこと
map()
関数を適用して結果をイテレータで返す
基本形:result = list(map(関数, イテラブル, イテラブル, ….)) ※イテラブルは複数でも可
# イテラブルオブジェクト1つの例 def square(x): # 値を2乗する関数 return x**2 lst = [1, 2, 3, 4, 5] result = list(map(square, lst)) # 戻り値はイテレータなのでlist()に入れる print(result) # [1, 4, 9, 16, 25] # ↓ # これをlambda式で表すと lst = [1, 2, 3, 4, 5] result = list(map(lambda x: x**2, lst)) print(result) # [1, 4, 9, 16, 25] # イテラブルオブジェクト2つの例 def square_cube(x,y): # 第1引数は値を2乗、第2引数は値を3乗する関数 return x**2, y**3 lst1 = [1, 2, 3, 4, 5] lst2 = [6, 7, 8, 9, 10] result = list(map(square_cube, lst1, lst2)) # 戻り値はイテレータなのでlist()に入れる print(result) # [(1, 216), (4, 343), (9, 512), (16, 729), (25, 1000)] # ↓ # これをlambda式で表すと lst1 = [1, 2, 3, 4, 5] lst2 = [6, 7, 8, 9, 10] result = list(map(lambda x,y:(x**2, y**3), lst1, lst2)) # lambda式の複数計算は()で囲えばタプルで返るし、[]で囲えばリストで返る print(result) # [(1, 216), (4, 343), (9, 512), (16, 729), (25, 1000)]
filter()
関数の条件を満たす要素を抽出してイテレータを返す
基本形:result = list(filter(関数, イテラブル)) ※イテラブルは1つのみ
# イテラブルオブジェクトの例 def is_odd(x): # 奇数を判別する関数 return x % 2 != 0 lst = [1, 2, 3, 4, 5] result = list(filter(is_odd, lst)) print(result) # [1, 3, 5] # ↓ # これをlambda式で表すと lst = [1, 2, 3, 4, 5] result = list(filter(lambda x: x % 2 != 0, lst)) # 戻り値はイテレータなのでlist()に入れる print(result) # [1, 3, 5]
reduce()
指定した関数を使って、イテラブルの要素を畳み込む
基本形:from functools import reduce ※モジュールの読み込みが必要(Python3から)
result = reduce(関数, イテラブル)
from functools import reduce # モジュールの読み込み # 加算の畳み込み def add_nums(x, y): return x + y lst = [1, 2, 3, 4, 5] result = reduce(add_nums, lst) print(result) # 15 # ↓ # これをlambda式で表すと lst = [1, 2, 3, 4, 5] result = reduce(lambda x, y: x + y, lst) print(result) # 15 # 乗算の畳み込み def multiply_nums(x, y): return x * y result = reduce(multiply_nums, lst) print(result) # 120 # ↓ # これをlambda式で表すと lst = [1, 2, 3, 4, 5] result = reduce(lambda x, y: x * y, lst) print(result) # 120
便利な使い方
リストの要素を一つずつstrとして取り出して繋ぎ、intに変換することができる
from functools import reduce # モジュールの読み込み def add_nums(x, y): return x + y # ここでは加算ではなく文字列の繋げ合わせの意味 lst = [1, 2, 3, 4, 5] result = int(reduce(add_nums, [str(e) for e in lst])) print(result) # 12345 # ↓ # これをlambda式で表すと lst = [1, 2, 3, 4, 5] result = int(reduce(lambda x, y: x + y, [str(e) for e in lst])) print(result) # 12345
partial()
対象の関数と、関数で固定したい引数の値を「引数=値」という形で指定。
引数を指定値で固定した「関数」が戻り値となり、以降の処理でfunc()として実行できる。
基本形:from functools import partial ※モジュールの読み込みが必要
func = partial(関数, 引数=値)
from functools import partial # モジュールの読み込み # べき乗する pow関数(組み込み) を使用した例 func2 = partial(pow, exp=2) # べき乗の係数を2で固定 print(func2(2)) print(func2(3)) # 4 # 9 func3 = partial(pow, exp=3) # べき乗の係数を3で固定 print(func3(2)) print(func3(3)) # 8 # 27