df['age'][5]のように[]を二段にしてアクセスすると発生する。これはchained indexingと呼ばれ、やってはいけない。 df.loc['age', 5]のように.locを使えば回避できる。 この警告が出る理由は以下に詳しく書かれているので是非読むことをオススメします。 日本語で詳細な解説が読めるとは、ありがたや~
Bitvise SSH Serverにログインすると直後に接続が切れる
sshサーバのログには以下のメッセージが出ていた。
<event seq="52" time="2019-05-02 20:41:20.671086 +0900" app="BvSshServer 7.21" name="W_SESSION_DISCONNECTED_ABNORMALLY" desc="Session disconnected abnormally."> <session id="1006" service="SSH" remoteAddress="192.168.0.100:59781"/> <parameters disconnectReason="FlowError"/> <error type="Flow" component="SshManager/transport/kexHandler" class="Flow" code="ComponentException" description="Exception in component: Windows CNG (x64) with additions: AsymKey: CngAgree: unexpected secretData->cbStruct"/> </event>
原因はBitvise SSH Serverの不具合で、Windowsのバージョンが1803以降だとログインできなくなるらしい。 Bitvise SSH Serverをバージョンアップすると直った。
参考:
pandas.qcutはcutする列の値に重複があると挙動がおかしくなることがある
現象は以下。
- TitanicのtrainデータのAgeの欠損値を22.0で埋める
pd.qcut(train["Age"], 4, duplicates="drop").value_counts()
を実行すると以下のようになり、要素数にかなり偏りができる
(0.419, 22.0] 408 (24.0, 35.0] 220 (35.0, 80.0] 217 (22.0, 24.0] 46 Name: Age, dtype: int64
「境界値をずらすともっと偏るのでしょうが無い」という状況なのかなと思いきや、そうでもなく、例えば以下の方が良い分割方法のように見える。
pd.qcut(train["Age"], [0, .2, .5, .75, 1.], duplicates="drop").value_counts()
(20.0, 24.0] 275 (24.0, 35.0] 220 (35.0, 80.0] 217 (0.419, 20.0] 179 Name: Age, dtype: int64
これはpandasの不具合なんだろうか。。値の重複があるときはqcutを使わないようにするか。。
.pyファイルの絶対パスの取得方法
str(Path(__file__))
だと、JupyterNotebookで実行した時にエラーになるという問題がある。
os.path.abspath("__file__")
であればJupyterNotebookでも実行可能。
参考:
JupyterNotebookで親階層のモジュールをimportする方法
ディレクトリ階層が以下のようになっている場合。
grand_parent_dir > parent_dir > child_dir
parent_dir/init.pyに書いている関数をimportして使いたいとする。
child_dirの下にJupyterNotebookがあるとする。
その場合、JupyterNotebookで以下のように書いても読み込めない。
from ..parent_dir import func
Jupyterは親階層のファイルを読み込めないため。(多分セキュリティ的な問題で) でも以下のようにsys.pathにpathを追加すると読み込めるようになる。 注意点としては、parent_dirまでのpathを追加してもだめで、grand_parent_dirまでのpathを追加しないといけない。 でないとparent_dir/init.py内の関数をimportできなかった。
import sys, os from pathlib import Path sys.path.append(str(Path(os.path.dirname(os.path.abspath("__file__"))).parent.parent))
参考:
DataFrameの型指定をしてサイズを削減する手順を自動化
以前の記事でDataFrameの各列の型を指定してサイズを小さく出来ると書いたが、それを自動化する。
以下を使ってcsvを読み込むとサイズを自動的に削減してくれる。一度全部読み込んでから型変換しているので、 処理途中で使うメモリ量は増える。csvはこれを使ってDataFrameに変換した後、Feather形式で保存し以降はそれを使うようにするといい。
def read_csv(filename: str, verbose: bool = True) -> pd.DataFrame: # Seriesの型を最適なものにすることでメモリを削減する。 # float16はFeather形式で保存出来ないため使用しない。 df: pd.DataFrame = pd.read_csv(f"{INPUT_PATH}/{filename}") start_mem: float = df.memory_usage().sum() / 1024 ** 2 for col in df.columns: _set_optimized_type(col, df) end_mem: float = df.memory_usage().sum() / 1024 ** 2 _print_result(end_mem, start_mem, verbose) return df def _print_result(end_mem: float, start_mem: float, verbose: bool): if verbose: reduce_percent: float = 100 * (start_mem - end_mem) / start_mem print('Mem. usage decreased to {:5.2f} Mb ({:.1f}% reduction)'.format(end_mem, reduce_percent)) def _set_optimized_type(col: str, df: pd.DataFrame): numerics: List[str] = ['int16', 'int32', 'int64', 'float32', 'float64'] col_type: List[str] = df[col].dtypes if col_type in numerics: if str(col_type)[:3] == 'int': df[col] = df[col].astype(_to_optimized_int_type(df[col].min(), df[col].max())) else: df[col] = df[col].astype(_to_optimized_float_type(df[col].min(), df[col].max())) def _to_optimized_int_type(c_min: int, c_max: int): if np.iinfo(np.int8).min < c_min and c_max < np.iinfo(np.int8).max: return np.int8 elif np.iinfo(np.int16).min < c_min and c_max < np.iinfo(np.int16).max: return np.int16 elif np.iinfo(np.int32).min < c_min and c_max < np.iinfo(np.int32).max: return np.int32 elif np.iinfo(np.int64).min < c_min and c_max < np.iinfo(np.int64).max: return np.int64 def _to_optimized_float_type(c_min: float, c_max: float): if np.finfo(np.float32).min < c_min and c_max < np.finfo(np.float32).max: return np.float32 else: return np.float64
参考: