## 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