python pandas コード備忘録


df.copy(deep = False)

deep = True(デフォルト):元のdfの行列・値を両方保持するためメモリを消費する。
deep = False:元のdfの行列のみ保持するため、deep = Trueよりもメモリを消費しない。

df.drop

inplace = False(デフォルト):対象のオブジェクトを返すのみ。
inplace = True:削除結果を反映させる。

    train_df_shallow =  train_df.copy(deep=False)
    train_df_shallow.drop("Sale",axis = 1,inplace= True)

jupyter notebookにおいて、pandasで表示が省略されるのを防ぐ

    pd.set_option('display.max_columns', 160) # 160番目の列まで全て強制表示
    pd.set_option('display.max_columns', None) # 全て強制表示

get_dummiesの使い方

get_dummiesは、文字列のまま使用できるので、いったんlabel列を文字列に戻す。

    df['label'] = le.inverse_transform(df['label'])
    df
size price label
1 100 cola
2 150 tea
3 200 coffee

get_dummiesでlabel列をダミー変数化して、元のDataFrameに結合する。

    df_dummy = pd.get_dummies(df['label'])
    df2 = pd.concat([df.drop(['label'],axis=1),df_dummy],axis=1)
    df2
size price coffee cola tea
1 100 0 1 0
2 150 0 0 1
3 200 1 0 0

これでダミー変数化は完成した。

多重共線性

回帰分析などにダミー変数を使用したい場合は、変数同士の相関が高いと多重共線性という問題が発生するため、one-hotエンコーディングの配列から列の1つを削除して使用しなければならない。例えばCoffee列を削除しても、cola列とtea列がともに0であればcoffeeであることがわかるので、情報としての欠落はない。
get_dummieのdrop_firstパラメータにTrueを渡すと最初の列を削除できる。

    df_dummy = pd.get_dummies(df['label'],drop_first = True)
    df3 = pd.concat([df.drop(['label'],axis=1),df_dummy],axis=1)
    df3
size price cola tea
1 100 1 0
2 150 0 1
3 200 0 0

重回帰分析などでは、カテゴリーの数がN個ある場合、N個のダミー変数を作ると予測できないため、どれか1個の変数を除外します。scikit-learnの重回帰分析 LinearRegression() では、この問題を回避する設計にしているようで、N個のダミー変数を作成しても動作します。

enumerate関数(forループでインデックスを取得できる)

Pythonのenumerate()関数を使うと、forループの中でリスト(配列)などのイテラブルオブジェクトの要素と同時にインデックス番号(カウント、順番)を取得できる。

  • enumerate関数を使ったforループ

引数にリストなどのイテラブルオブジェクトを指定する。
インデックス番号, 要素の順に取得できる。

0以外の数値から開始したい場合は、enumerate()関数の第二引数に任意の開始数値を指定する。

    for i, name in enumerate(l, 1):
        print(i, name)
    # 1 Alice
    # 2 Bob
    # 3 Charlie

カレントディレクトリの取得

    import os
    os.getcwd()

ファイル選択ダイアログの表示

    root = tkinter.Tk()
    root.withdraw()
    fTyp = [("", "*.csv")]
    iDir = os.path.abspath(current_dir)
    tkinter.messagebox.showinfo('売上可視化プログラム', '処理したいCSVファイルを選択してください!')
    file = tkinter.filedialog.askopenfilename(filetypes = fTyp,initialdir = iDir)
    if file == "":
        print("CSV選択がキャンセルされました。終了します。")
        sys.exit(1)

文字判定

大文字かどうかを判定(isupper)

str.isupper()を使います。
文字列中の英字 全てが大文字、かつ1文字以上の場合はTrue、そうでない場合はFalseを返します。

    # 全て英字大文字
    >>> 'ABCDE'.isupper()
    True

    # 全て英字小文字
    >>> 'abcde'.isupper()
    False

    # 英字 大文字・小文字混在
    >>> 'Abcde'.isupper()
    False

    # 英数字混在
    >>> 'ABC12'.isupper()
    True

    # 英数字以外も混在
    >>> 'Aa12\*'.isupper()
    False

小文字かどうかを判定(islower)

str.islower()を使います。
文字列中の英字(上記参照)全てが小文字で、かつそれが1文字以上ある場合はTrue、そうでない場合はFalseを返します。

    # 全て英字大文字
    >>> 'ABCDE'.islower()
    False

    # 全て英字小文字
    >>> 'abcde'.islower()
    True

    # 英字 大文字・小文字混在
    >>> 'Abcde'.islower()
    False

    # 英数字混在
    >>> 'abc12'.islower()
    True

    # 英数字も混在
    >>> 'Aa12\*'.islower()
    False

英数字であることを判定(isalnum)

str.isalnum()を使います。
文字列中の全ての文字が英数字で、かつ1文字以上ある場合はTrue、そうでない場合はFalseを返します。

    # 全て英字大文字
    >>> 'ABCDE'.isalnum()
    True

    # 全て英字小文字
    >>> 'abcde'.isalnum()
    True

    # 英字 大文字・小文字混在
    >>> 'Abcde'.isalnum()
    True

    # 英数字混在
    >>> 'abc12'.isalnum()
    True

    # 英数字以外混在
    >>> 'Aa12\*'.isalnum()
    False

英字かどうかを判定(isalpha)

str.isalpha()を使います。
文字列中の全ての文字が英字(上記参照)で、かつ1文字以上ある場合はTrue、そうでない場合はFalseを返します。

    # 全て英字大文字
    >>> 'ABCDE'.isalpha()
    True

    # 全て英字小文字
    >>> 'abced'.isalpha()
    True

    # 英字 大文字・小文字混在
    >>> 'Abced'.isalpha()
    True

    # 英数字混在
    >>> 'abc12'.isalpha()
    False

    # 英数字以外混在
    >>> 'Aa12\*'.isalpha()
    False

ASCII文字列かどうかを判定(isascii)

str.isascii()を使います。
文字列が空、または全ての文字が ASCII( U+0000 〜 U+007F) である場合はTrue、それ以外の場合はFalseを返します。
Python3.7から追加されたメソッドなのでバージョンに注意。

    # 全て英字大文字
    >>> 'ABCDE'.isascii()
    True

    # 全て英字小文字
    >>> 'abced'.isascii()
    True

    # 英字 大文字・小文字混在
    >>> 'abc12'.isascii()
    True

    # 英数字以外混在
    >>> 'Aa12\*'.isascii()
    True

    # ASCIIコード以外
    >>> 'あ'.isascii()
    False

タイトルケース文字列かどうかを判定(istitle)

str.istitle()を使います。
タイトルケースとは、文の最初以外の単語についても先頭文字を大文字にすることです。
このメソッドは以下の2つを満たす場合にTrueを返します。

  • 大文字は、英字以外の文字の後のみに置かれる
  • 小文字は、英字の後にだけ続く

よって、以下の点に注意が必要です。

  • アポストロフィー(’)の後の文字が小文字だとタイトルケースと判定されません(例:Tom’s → Tom’S)
  • 翻訳業界などでは4文字未満の前置詞や接続詞(on, theなど)はこれを適用しないルールがあるようですが、このメソッドはこのルールが適用されません

    # 文章の最初の文字のみ大文字
    >>> "Tom's watch is on the table.".istitle()
    False

    # istitle()でTrueとなるタイトルケース
    >>> "Tom'S Watch Is On The Table.".istitle()
    True

    # アポストロフィー(')の後の文字が小文字だとFalse
    >>> "Tom's Watch Is On The Table.".istitle()
    False

    # onやtheの先頭文字が小文字だとFalse
    >>> "Tom'S Watch Is on the Table.".istitle()
    False

文字コードと文字を相互変換

文字をUnicodeコードポイントに変換: ord()

ord()の引数に文字(1文字の文字列)を指定すると、その文字のUnicodeコードポイントが整数intで返される。

    i = ord('A')
    print(i)
    # 65

    print(type(i))
    # <class 'int'>
  • Unicodeコードポイントは16進数で表記されることが多い。整数を16進数表記の文字列に変換するには組み込み関数hex()を使う。

    s = hex(i)
    print(s)
    # 0x41

    print(type(s))
    # <class 'str'>
  • 組み込み関数format()を使うと、ゼロ埋めや0xの有無など、より細かい書式を指定できる。

    print(format(i, '04x'))
    # 0041

    print(format(i, '#06x'))
    # 0x0041
  • 特定の文字の16進数表記のUnicodeコードポイントを取得する処理を一気に書くと以下のようになる。

    print(format(ord('X'), '#08x'))
    # 0x000058

    print(format(ord('💯'), '#08x'))
    # 0x01f4af

Unicodeコードポイントを文字に変換: chr()

chr()の引数に整数を指定すると、その値がUnicodeコードポイントである文字が文字列strで返される。

    print(chr(65))
    # A

    print(type(chr(65)))
    # <class 'str'>

Pythonでは、0xをつけると数値を16進数で記述できるので、16進数表記のUnicodeコードポイントが分かっていればそのままchr()の引数として指定できる。ゼロ埋めされていても問題ない。

    print(65 == 0x41)
    # True

    print(chr(0x41))
    # A

    print(chr(0x000041))
    # A
  • Unicodeコードポイントを表す16進数表記の文字列からそのコードポイントの文字を取得したい場合、16進数表記の文字列を整数intに変換してからchr()に渡す。

16進数表記の文字列を整数intに変換するにはint()を使う。第一引数に文字列、第二引数に基数16を指定する。

    s = '0x0041'

    print(int(s, 16))
    # 65

    print(chr(int(s, 16)))
    # A
  • 16進数表記の文字列をint()で整数に変換する場合、文字列に0xがついていれば第二引数は0でもOK。16進数の数値・文字列の扱いについての詳細は以下の記事を参照。

  • UnicodeコードポイントはU+XXXXの形で記述されることも多い。このような文字列をそのコードポイントの文字に変換するにはスライスで数値部分のみを選択すればよい。

    s = 'U+0041'

    print(s[2:])
    # 0041

    print(chr(int(s[2:], 16)))
    # A

文字列をUnicodeコードポイントで記述: \x, \u, \U

文字列リテラルの中では\x, \u, \Uに続けて16進数表記のUnicodeコードポイントを記述でき、その文字として扱われる。
\xXX, \uXXXX, \UXXXXXXXXのように、それぞれ2桁、4桁、8桁の16進数である必要がある。桁数が合っていないとエラー。

    print('\x41')
    # A

    print('\u0041')
    # A

    print('\U00000041')
    # A

    print('\U0001f4af')
    # 💯

    # print('\u041')
    # SyntaxError: (unicode error) 'unicodeescape' codec can't decode bytes in position 0-4: truncated \uXXXX escape

    # print('\U0000041')
    # SyntaxError: (unicode error) 'unicodeescape' codec can't decode bytes in position 0-8: truncated \UXXXXXXXX escape

各コードが1文字として扱われる。文字数を返す組み込み関数len()で確認できる。

    print('\u0041\u0042\u0043')
    # ABC

    print(len('\u0041\u0042\u0043'))
    # 3

エスケープシーケンスが無効化されるraw文字列ではそのままの文字の並びとして認識されるので注意。

    print(r'\u0041\u0042\u0043')
    # \u0041\u0042\u0043

    print(len(r'\u0041\u0042\u0043'))
    # 18