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