タグ別アーカイブ: pandas

python pandas データフレームに空のシリースを追加すると、またしても警告が…

またしても SettingWithCopyWarning の警告が出た。

既にあるデータフレーム(シリーズ)に、空の新しいシリーズを作ってすぐ追加したい場合に。

こんな警告が出てくる。

便利APIやアクセサ経由でデータフレームを操作した時に出た警告と同じだけど、

今度は、自分のコード自体がエラーの発生箇所になってるけど、
指定されたURLを覗いてみると、原因は以前の時と同じみたいだ。

pythonの中で二度呼びされるから、予期しない結果になるかも知れないよ、とのこと。

Since the chained indexing is 2 calls, it is possible that either call may return a copy of the data because of the way it is sliced. Thus when setting, you are actually setting a copy, and not the original frame data. It is impossible for pandas to figure this out because their are 2 separate python operations that are not connected.

The SettingWithCopy warning is a ‘heuristic’ to detect this (meaning it tends to catch most cases but is simply a lightweight check). Figuring this out for real is way complicated.

The .loc operation is a single python operation, and thus can select a slice (which still may be a copy), but allows pandas to assign that slice back into the frame after it is modified, thus setting the values as you would think.

The reason for having the SettingWithCopy warning is this. Sometimes when you slice an array you will simply get a view back, which means you can set it no problem. However, even a single dtyped array can generate a copy if it is sliced in a particular way. A multi-dtyped DataFrame (meaning it has say float and object data), will almost always yield a copy. Whether a view is created is dependent on the memory layout of the array.

0のリストを二つ作ったつもりが、一つしか作られてないって事なんでしょね。

ちなみに初期値をあたえないで、こう書くと、警告は出ない。

けど、NaNで都合が悪い場合は、改めて初期値を入れてやんなきゃならない。

MacBook Pro Retina 2015の環境設定

結局、2015年に新調したのは「新しいMacBook」じゃなくて、
MacBook Pro Retina 15 2015 でした。

普段持ち歩いている MacBook Air 2014 の出来が良過ぎて、
新しいMacBookに買い替えるまでには至りませんでした。

12インチRetinaディスプレイが手に入る代わりに、
Airのバッテリー持ちと計算速度と20万円が無くなるのはチョット。。。

そして。
愛用していた2012のMacBook Pro Retina 15にはBootCampを使って、
嫁さんのWindowsPCに化かしました。

さて。
会社から帰宅したら、新しい MacBook Pro Retina 15が届いていたので
早速環境整備です。

最初の電源投入時にあった10個弱のアップデートを更新しつつ、
並行してChromeとGoogle日本語入力、Dropboxをインストール。

次に、 Homebrew をインストールして、
最新のEmacsをビルドします。

ビルドが終わる頃には、Dropbox にある.emacs.d と同期完了するので、
いつもの emacs が使えるようになります。

ショートカットキーを設定するため、
下記の通り Emacs.appをApplicationに登録しておきます。

Chrome/ターミナル/Emacsを、以前と同じキーボードショートカットキーに登録して、
使い勝手は、ほぼ2012 MBPRと同等になりました。

キーボードショートカットアプリに、今回は BetterTouchTool を使ってみます。
キーボード以外にトラックパッドなどにも色々な機能が追加できる様です。
使い勝手が良くなれば、シンプルな Spark.app に戻すかも知れません。

(結局、あとで Spark.app に戻しました)

最後に、最近多用しているpythonとライブラリ類を追加します。

pythonは、Macの標準ではなく、Homebrewのpython2.7を使います。
それと直ぐに必要になるライブラリをインストールしておきます。

Dropboxに開発中のソースとホームディレクトリの設定ファイルが全て入れてあるので、
これで一先ず、以前と同様の開発環境のできあがりです。

この後、MAMP/Jenkinsを整備して、テスト環境を作り直します。

今迄は諸般の事情でJenkinsをユーザー権限の範囲で使う必要があり、
ゴニョゴニョ設定していたけど、今回からはスッキリ標準的な構成にしようと思います。

python pandas データフレームの日本語で、文字の検索・置換がうまくいかない

m2jのデータを加工するのに、通貨ペアの名前が
‘USD/JPY’だったり’USDJPY’だったりするので統一したい。

とりあえず、さくっと書いてみたけど、
思ったように動作しなくて、データフレームが壊れてしまう。

数字はちゃんと変換されるので、文字コード関係かも知れない。
Shift-JISで使いたいからなぁ。。。

replaceには、encodingオプションなどないし。
ファイルから読み込む時に、str型に変換してしまっているし。

もう少し見てみると。
中でUnicodeに変換するのに失敗しているみたい。

試しに、unicodeのデータフレームを作ってみたら、
正しく検索や置換が動作ることを確認した。

わざわざstr型に変換してみたけれど、
やっぱりUnicodeに統一するのが正解みたいだ。

という訳で。
Pythonの文字コードの扱いについて調べてみた。

PythonのUnicodeEncodeErrorを知る
http://lab.hde.co.jp/2008/08/pythonunicodeencodeerror.html

とは言え。
外のShift JISなcsvファイルからpandasに読み込むときには
どうするのが良いのかな。

read_csvした直後は、もうstr型になってしまっているし。

全部の要素をチェックするループを書くのはチョット。。。
なので、Series用のstr アクセサを書くのが、妥当そう。

strアクセサは、 内部のデータ型が文字列(str か unicode ) 型のとき、
その要素に対して、一通りの文字列用メソッドを適用することができる。

使えるstrアクセサ一覧
http://pandas.pydata.org/pandas-docs/stable/api.html#string-handling

当然、encodeやreplaceもあった。

例えば

これで、文字列の要素がUnicodeに置き換わって、必要な文字置換も完了。

アクセサを使わないで文字列検索や置換を行なう時には、
encode(‘cp932’)しなくても動作するのに。

知らないとハマるよね、コレ。

python pandas データフレームへの代入で警告が出る

Cygwinのpythonだと問題なかったプログラムで、
Macだと SettingWithCopyWarning の警告が出た。

何でCygwinだと稽古が出なかったのかは不明だけど。
SettingWithCopyWarning は出ないようにした方が良さそうだ、
という話。

外のcsvの内容をpandasに読ませたのは良いけど、
そのままの文字列では不都合なので要素の中身を加工しようとして、
アクセサを使ってこんな風に書くと。

警告が出てくる。
結果を見たところ、意図した通りに動作はしているけれど、大変気持悪い。

この原因は、pandasの便利機能を使って要素の選択を行う際に、
中で二度呼びされる…うんぬん。で、予期しない結果になるかも知れないよ、とのこと。

So, why does this show the SettingWithCopy warning / and possibly not work when you do chained indexing and assignment:

dfmi[‘one’][‘second’] = value
Since the chained indexing is 2 calls, it is possible that either call may return a copy of the data because of the way it is sliced. Thus when setting, you are actually setting a copy, and not the original frame data. It is impossible for pandas to figure this out because their are 2 separate python operations that are not connected.

The SettingWithCopy warning is a ‘heuristic’ to detect this (meaning it tends to catch most cases but is simply a lightweight check). Figuring this out for real is way complicated.

The .loc operation is a single python operation, and thus can select a slice (which still may be a copy), but allows pandas to assign that slice back into the frame after it is modified, thus setting the values as you would think.

The reason for having the SettingWithCopy warning is this. Sometimes when you slice an array you will simply get a view back, which means you can set it no problem. However, even a single dtyped array can generate a copy if it is sliced in a particular way. A multi-dtyped DataFrame (meaning it has say float and object data), will almost always yield a copy. Whether a view is created is dependent on the memory layout of the array.

pandasの実装を気にして使っていられないし、
予想外の箇所でこのエラーに遭遇することもある。

なので、アクセサを避けて、言われた通りの使い方をしてみる。

ところが、このままでは警告は消えない。
データのクレンジング作業途中でindexに欠番があったりすると、
そのままでは、さくっと差し替えることも、ちょっと面倒。

あぁ、同じことを言ってる人がいる。
http://stackoverflow.com/questions/25698710/replace-all-occurrences-of-a-string-in-a-pandas-dataframe-python

アクセサを使わないで全体に正規表現で置換をかけると、
SettingWithCopyは出ない。

Columで限定できてないけど、これでOK。

しかも、 encode(‘cp932’) しなくても文字列置換ができた。

この変のAPIの動きは、最近のバージョンで変更になったみたいなので、
要注意。

せっかく便利なアクセサなのに、かえって混乱してしまった。
今後、また仕様が変わるのかも。

python pandasで日本語のcsvファイルを読み込む

pandasのデータフレームやなんかを使いたいけど
読みたいcsvファイルが日本語で、コードがShift-JISな場合、
ちょっとイヤな実装になる。

Python3に乗り換えれば幸せになれるのかな。
でも、GAEやなんかは、まだ当分2.7だろうし。。。

m2jの注文履歴のcsvとか。

予めcsvファイルをUTF-8に変換しておけば、文字コードを意識しなくて済む。

ダウンロードしたままのShift-JISだと、
read_csvで encoding を指定しなければならない。

で、中で使われているstr型の文字コードはUnicodeかutfか、
何かに統一されているのかと思ったら、そうじゃないみたい。

なので、表示したり比較したりするたび
.encode(‘utf-8’) とか、つけないといけない。

場当たり的に対応してると、出来上がったコードは汚くなるなぁ。
良い方法はないものか。