Pandasでmatplotlibみたいに描画する

これまでPandasとmatplotlibを一緒に使う機会がなかったんですが,Pandasにも描画機能があります.しかもこれが結構便利!とうことで早速使ってみたので,ログとして残しておきます.

import pandas as pd
import pylab
import matplotlib
import matplotlib.pyplot as plt

plt.style.use('ggplot') # ggplotを使う
font = {'family' : 'meiryo'} # フォントをメイリオにする
matplotlib.rc('font', **font) # 

# データフレームの定義
df = pd.DataFrame({'Time': ['10:00:00', '10:00:01', '10:00:02', '10:00:03', '10:00:04','10:00:05', '10:00:06', '10:00:07', '10:00:08', '10:00:09'],
                   'Value1': [25, 30, 104, 52, 41, 91, 102, 40 ,101 ,97],
                    'Value2': [45, 19, 34, 19, 78, 148, 45, 53 ,74 ,32]})

# サイズの変換
pylab.figure(figsize=(9, 6))

# グラフを描く
df.plot()

# 画像ファイルの保存
plt.savefig("image.png")

f:id:shu10038:20170226084921p:plain






    
    
  

データフレームからarrayに変換:pandas numpy

機械学習のライブラリなどを使おうとすると,データフレーム型からnumpyのarray型にしないと引数として渡せない場合があります.このデータフレームからarrayに変換する方法は色々あるんですが,一番簡単なのはas_matrix()を使うことでしょうか.

In [102]: import pandas as pd # pandasをインポート

In [103]: import numpy as np # numpyをインポート

# データフレームを定義する
In [104]: df = pd.DataFrame({'Time': ['10:00:00', '10:00:01', '10:00:02', '10:00:03', '10:00:04','10:00:05', '10:00:06', '10:00:07', '10:00:08', '10:00:09'],
     ...:                    'Value1': [25, 30, 104, 52, 41, 91, 102, 40 ,101 ,97],
     ...:                     'Value2': [45, 19, 34, 19, 78, 148, 45, 53 ,74 ,32]})

# データフレームの中身を確認する
In [105]: df
Out[105]: 
       Time  Value1  Value2
0  10:00:00      25      45
1  10:00:01      30      19
2  10:00:02     104      34
3  10:00:03      52      19
4  10:00:04      41      78
5  10:00:05      91     148
6  10:00:06     102      45
7  10:00:07      40      53
8  10:00:08     101      74
9  10:00:09      97      32

# .as_matrix()を呼び出す
In [106]: array = df.as_matrix()

# arrayに変換されたかを確認する
In [107]: array
Out[107]: 
array([['10:00:00', 25, 45],
       ['10:00:01', 30, 19],
       ['10:00:02', 104, 34],
       ..., 
       ['10:00:07', 40, 53],
       ['10:00:08', 101, 74],
       ['10:00:09', 97, 32]], dtype=object)

こんな感じ

2020/3/6追記

as_matrixはどうやら無くなるみたいですね.

FutureWarning: Method .as_matrix will be removed in a future version. Use .values instead.

とのこと.なので代わりに

df.values.tolist()

を使いますかな.

Pathを通した先のファイルの読み書きがおかしくなる

teratailのフォーマットが見やすいので,真似して書いてみます.

前提・実現したいこと

Pythonの3系を使っているのですが,どうやら開発環境のワークスペースを変えるとファイルを読むときにはワークスペースからパスを通さなくてはならないらしいです.なのでパス+ファイル名みたいな書き方をしていたのですが,エラーが出てしまいます.

発生している問題・エラーメッセージ

たとえば

path = 'ファイルまでのパス'

df = pd.read_csv( path + 'ファイル名.csv')

と書くと

File b'ファイルまでのパス\\ファイル名.csv' does not exist

という具合に何故か\\(円マークもしくはバックスラッシュが2つならんでしまします)

またグラフを出力しようとすると,'path'の後ろの文字列とつながってしまって'末尾の円マーク以降の文字列+「ファイル名」'みたいになってしまいます.

解決策

色々試してみましたが,作業ディレクトリを変えるのが一番早いと思います.

import os

# pathの設定
os.chdir("作業しているフォルダ名")

Jupyter Notebookの設定を色々変えてみる

PythonといえばSpyderを使ったりJupyter Notebookをしてますが,Jupyter Notebookの方はフォントが気に入らなかったりします.そこでnbextensionsをつかって色々いじってみたんですが,忘れそうなのでこのブログにメモしておきます.

ちなみにAnacondaはAnaconda 4.3.0 For Windowsを使っています.

ダウンロードは下記のサイトからしました.
GitHub - ipython-contrib/jupyter_contrib_nbextensions: A collection of various notebook extensions for Jupyter

ダウンロードというかここのサイトに書いてあったとおりにやっただけなんですけどね~

最初は404 errorが出てしまいましたが,「conda install -c conda-forge jupyter_contrib_nbextensions」と入力したらうまくいきました!

CSVファイルが読み込めない

症状

Spyderを使っていてCSVファイルが読み込めなくなる

File b'ファイル名.csv' does not exist

原因

Spyderの設定でワークスペースを変えるとこうなる

対処

パスを通せば良い

path = '++++\名前\'

df = pd.read_csv(path + "dataset.csv",header = None)


パスを移動させても良い

csv_data  = pd.read_csv('./path/dataset.csv')

データの集約とグループ演算をやってみる Pandas

PythonのPandasを使っていると,例えば同じ名前の者同士を一括りにして,平均なり最大値を出したり,という処理を迫られることがあります.私自身,この間それを迫られた訳で,オライリーの本を読んで,どういう挙動を示すか色々試してみました.せっかくなので試した内容を,この記事にメモしておきたいと思います.

www.oreilly.co.jp


さて,今回のデータフレームは下のものを使います.

In [62]: df = pd.DataFrame(
    ...:          {'Time': ['10:00:00', '10:00:01', '10:00:02', '10:00:03', '10:00:04','10:00:05', '10:00:06', '10:00:07', '10:00:08', '10:00:09'],
    ...:         'Sensor': ['T-A', 'T-B', 'T-C', 'T-B', 'T-C', 'T-A', 'T-C', 'T-B' ,'T-B' ,'T-C'],
    ...:          'Value': [25, 30, 104, 52, 41, 91, 102, 40 ,101 ,97]}
    ...:          )

# 今回使用するデータ
In [63]: df
Out[63]: 
  Sensor      Time  Value
0    T-A  10:00:00     25
1    T-B  10:00:01     30
2    T-C  10:00:02    104
3    T-B  10:00:03     52
4    T-C  10:00:04     41
5    T-A  10:00:05     91
6    T-C  10:00:06    102
7    T-B  10:00:07     40
8    T-B  10:00:08    101
9    T-C  10:00:09     97

実験か何かでセンサ類を使って,得られたデータを分析することを想定しています.それぞれ,

  • 'Time':センサデータが得られた時間
  • 'Sensor':センサの型番
  • 'Value':センサから得られた値

を示しています.ちょっと問題設定としては苦しいかもしれませんが,練習のためと思ってご了承ください.

まずは基本的な使い方編

センサの型番で括るとこんな感じです.

# 今回使用するデータ
In [63]: df
Out[63]: 
  Sensor      Time  Value
0    T-A  10:00:00     25
1    T-B  10:00:01     30
2    T-C  10:00:02    104
3    T-B  10:00:03     52
4    T-C  10:00:04     41
5    T-A  10:00:05     91
6    T-C  10:00:06    102
7    T-B  10:00:07     40
8    T-B  10:00:08    101
9    T-C  10:00:09     97

# 'Sensor'で括る
In [101]: df.groupby('Sensor').groups
Out[101]: 
{'T-A': Int64Index([0, 5], dtype='int64'),
 'T-B': Int64Index([1, 3, 7, 8], dtype='int64'),
 'T-C': Int64Index([2, 4, 6, 9], dtype='int64')}

演算をしてみる

括った塊を演算にかけることが出来ます.例えば下の場合は'Sensor'でグルーピングして平均を求めています.

# 'Sensor'で括り,'T-A''T-B''T-C'のそれぞれの'Value'に対する平均値を求める
In [66]: df_mean = df.groupby('Sensor')['Value'].mean()

In [67]: df_mean
Out[67]: 
Sensor
T-A    58.00
T-B    55.75
T-C    86.00
Name: Value, dtype: float64

時間ごとに集計してみよう編

In [63]: df
Out[63]: 
  Sensor      Time  Value
0    T-A  10:00:00     25
1    T-B  10:00:01     30
2    T-C  10:00:02    104
3    T-B  10:00:03     52
4    T-C  10:00:04     41
5    T-A  10:00:05     91
6    T-C  10:00:06    102
7    T-B  10:00:07     40
8    T-B  10:00:08    101
9    T-C  10:00:09     97

ここで無理やりTime列をDateTime 型に変換して列を追加します

In [93]: df2 = df.assign(time2=lambda xx: pd.to_datetime(xx.Time))

In [94]: df2
Out[94]: 
  Sensor      Time  Value               time2
0    T-A  10:00:00     25 2017-02-05 10:00:00
1    T-B  10:00:01     30 2017-02-05 10:00:01
2    T-C  10:00:02    104 2017-02-05 10:00:02
3    T-B  10:00:03     52 2017-02-05 10:00:03
4    T-C  10:00:04     41 2017-02-05 10:00:04
5    T-A  10:00:05     91 2017-02-05 10:00:05
6    T-C  10:00:06    102 2017-02-05 10:00:06
7    T-B  10:00:07     40 2017-02-05 10:00:07
8    T-B  10:00:08    101 2017-02-05 10:00:08
9    T-C  10:00:09     97 2017-02-05 10:00:09

あとは無理やり

In [95]: df2.groupby(pd.Grouper(key='time2', freq='2s')).groups
Out[95]: 
{Timestamp('2017-02-05 10:00:00', freq='2S'): 2,
 Timestamp('2017-02-05 10:00:02', freq='2S'): 4,
 Timestamp('2017-02-05 10:00:04', freq='2S'): 6,
 Timestamp('2017-02-05 10:00:06', freq='2S'): 8,
 Timestamp('2017-02-05 10:00:08', freq='2S'): 10}
In [96]: df2.groupby(pd.Grouper(key='time2', freq='2s')).max()
Out[96]: 
                    Sensor      Time  Value
time2                                      
2017-02-05 10:00:00    T-B  10:00:01     30
2017-02-05 10:00:02    T-C  10:00:03    104
2017-02-05 10:00:04    T-C  10:00:05     91
2017-02-05 10:00:06    T-C  10:00:07    102
2017-02-05 10:00:08    T-C  10:00:09    101