第3章Pandasデータ処理(3.11-3.13)Pythonデータ科学マニュアル学習ノート

37668 ワード

3.11量子化文字列操作
3.11.1 Pandas文字列操作概要
import numpy as np
x = np.array([2,3,4,5,11,13])
x * 2
array([ 4,  6,  8, 10, 22, 26])

NumPyは文字列配列に単純なインタフェースを提供していないため,煩雑なforループによって問題を解決する必要がある.
data = ['peter','Paul','MARY','gUIDO']
[s.capitalize() for s in data]
['Peter', 'Paul', 'Mary', 'Guido']

データに欠落した値を追加すると、エラーが発生する可能性があります.
data = ['peter','Paul',None,'MARY','gUIDO']
[s.capitalize() for s in data]
---------------------------------------------------------------------------

AttributeError                            Traceback (most recent call last)

 in ()
      1 data = ['peter','Paul',None,'MARY','gUIDO']
----> 2 [s.capitalize() for s in data]


 in (.0)
      1 data = ['peter','Paul',None,'MARY','gUIDO']
----> 2 [s.capitalize() for s in data]


AttributeError: 'NoneType' object has no attribute 'capitalize'

Pandasが文字列を含むSeriesとIndexオブジェクトに提供するstrプロパティは、量子化文字列への操作を満たすとともに、欠落した値を正しく処理することができます.
import pandas as pd
names = pd.Series(data)
names
---------------------------------------------------------------------------

NameError                                 Traceback (most recent call last)

 in ()
      1 import pandas as pd
----> 2 names = pd.Series(data)
      3 names


NameError: name 'data' is not defined
names.str.capitalize()
0    Peter
1     Paul
2     None
3     Mary
4    Guido
dtype: object

3.11.2 Pandas文字列メソッドリスト
monte = pd.Series(['Graham Chapman','John Cleese','Terry Gilliam',
                  'Eric Idle', 'Terry Jones','Michael Palin'])

Python文字列メソッドと似た方法
len()
lower()
translate()
islower()
ljust()
upper()
startswith()
isupper()
rjust()
find()
endswith()
isdecimal()
center()
rfind()
isalnim()
isdecimal()
zfill()
index()
isalpha()
split()
strip()
rindex()
isdigit()
rspllit()
rstrip()
capitalize()
isspace()
partition()
lstrip()
swapcase()
istitle()
rpartition()
これらのメソッドの戻り値は異なります.たとえば、lower()メソッドは文字列Seriesを返します.
monte.str.lower()
0    graham chapman
1       john cleese
2     terry gilliam
3         eric idle
4       terry jones
5     michael palin
dtype: object

数値を返す方法もあります
monte.str.len()

ブール値を返すものもあります
monte.str.startswith('T')
0    False
1    False
2     True
3    False
4     True
5    False
dtype: bool

リストまたはその他の複合値を返すものもあります
monte.str.split()
0    [Graham, Chapman]
1       [John, Cleese]
2     [Terry, Gilliam]
3         [Eric, Idle]
4       [Terry, Jones]
5     [Michael, Palin]
dtype: object
monte.str.extract('([A-Za-z]+)')

0
0
Graham
1
John
2
Terry
3
Eric
4
Terry
5
Michael
monte.str.findall(F'^[^AEIOU].*[^aeiou]$')
0    [Graham Chapman]
1                  []
2     [Terry Gilliam]
3                  []
4       [Terry Jones]
5     [Michael Palin]
dtype: object

より多くの正規表現をSeriesとDataFrameに適用できれば-その他のPandas文字列メソッド
方法
説明
get()
要素インデックスの位置の値を取得します.インデックスは0から始まります.
slice()
要素のスライス値
slice_replace()
要素のスライス置換
cat()
接続文字列
repeat()
繰り返し要素
normalize()
文字列をUnicode仕様に置き換える
pad()
文字列の左または右にスペースを追加
wrap()
文字列を指定した幅で改行
join()
Seriesの各要素を区切り記号で接続する
get_dummies()
各要素のdummy変数をセパレータで抽出
#               
#  get(),slice()                    
monte.str[0:3]
0    Gra
1    Joh
2    Ter
3    Eri
4    Ter
5    Mic
dtype: object
full_monte = pd.DataFrame({'name': monte,
                          'info': ['b|c|d','b|d','a|c','b|d','b|c','b|c|d']})
full_monte['info'].str.get_dummies('|')

a
b
c
d
0
0
1
1
1
1
0
1
0
1
2
1
0
1
0
3
0
1
0
1
4
0
1
1
0
5
0
1
1
1
3.11.3ケース:レシピデータベース
3.12処理時系列
3.12.1 Pythonの日付と時刻ツール
1原生Pythonの日時ツール:datetimeとdateutil
from datetime import datetime
datetime(year=2015,month=7,day=4)
datetime.datetime(2015, 7, 4, 0, 0)
from dateutil import parser
date = parser.parse('4th of July,2015')
date
datetime.datetime(2015, 7, 4, 0, 0)
#           
date.strftime('%A')
'Saturday'

2時間タイプ配列:NumPyのdatetime 64タイプ-datetime 64は日付設定時に特定の入力タイプを決定する必要があります
import numpy as np
date = np.array('2015-07-04',dtype=np.datetime64)
date
array('2015-07-04', dtype='datetime64[D]')
date + np.arange(12)
array(['2015-07-04', '2015-07-05', '2015-07-06', '2015-07-07',
       '2015-07-08', '2015-07-09', '2015-07-10', '2015-07-11',
       '2015-07-12', '2015-07-13', '2015-07-14', '2015-07-15'],
      dtype='datetime64[D]')
np.datetime64('2015-07-04')
numpy.datetime64('2015-07-04')
np.datetime64('2015-07-04 12:00')
numpy.datetime64('2015-07-04T12:00')
np.datetime64('2015-07-04 12:59:59','ns')
numpy.datetime64('2015-07-04T12:59:59.000000000')

Pandasの日付と時間ツール:理想と現実の最適なソリューション
import pandas as pd
date = pd.to_datetime('4th of July,2015')
date
Timestamp('2015-07-04 00:00:00')
date.strftime('%A')
'Saturday'
date + pd.to_timedelta(np.arange(12),'D')
DatetimeIndex(['2015-07-04', '2015-07-05', '2015-07-06', '2015-07-07',
               '2015-07-08', '2015-07-09', '2015-07-10', '2015-07-11',
               '2015-07-12', '2015-07-13', '2015-07-14', '2015-07-15'],
              dtype='datetime64[ns]', freq=None)

3.12.2 Pandas時系列:時間を索引とする
index = pd.DatetimeIndex(['2014-07-04','2014-08-04',
                         '2015-07-04','2015-08-04'])
data = pd.Series([0,1,2,3],index=index)
data
2014-07-04    0
2014-08-04    1
2015-07-04    2
2015-08-04    3
dtype: int64
data['2014-07-04':'2015-07-04']
2014-07-04    0
2014-08-04    1
2015-07-04    2
dtype: int64
data['2015']
2015-07-04    2
2015-08-04    3
dtype: int64

3.12.3 Pandas時系列データ構造
dates = pd.to_datetime([datetime(2015,7,3),'4th of July,2015',
                       '2015-July-6','07-07-2015','20150708'])
dates
DatetimeIndex(['2015-07-03', '2015-07-04', '2015-07-06', '2015-07-07',
               '2015-07-08'],
              dtype='datetime64[ns]', freq=None)
dates.to_period('D')
PeriodIndex(['2015-07-03', '2015-07-04', '2015-07-06', '2015-07-07',
             '2015-07-08'],
            dtype='period[D]', freq='D')
dates-dates[0]
TimedeltaIndex(['0 days', '1 days', '3 days', '4 days', '5 days'], dtype='timedelta64[ns]', freq=None)

規則的な時間系列:pd.date_range() - pd.date_range()はタイムスタンプを処理できる-pd.period_range()は周期-pdを処理できる.timedelta_range()は、時間間隔-Pythonのrange()とNumPyのnpを処理することができる.arang()は、7点、終点、ステップコードで規則的な日付シーケンスを作成できます.
pd.date_range('2015-07-03','2015-7-10')
DatetimeIndex(['2015-07-03', '2015-07-04', '2015-07-05', '2015-07-06',
               '2015-07-07', '2015-07-08', '2015-07-09', '2015-07-10'],
              dtype='datetime64[ns]', freq='D')
pd.date_range('2015-07-03',periods=8)
DatetimeIndex(['2015-07-03', '2015-07-04', '2015-07-05', '2015-07-06',
               '2015-07-07', '2015-07-08', '2015-07-09', '2015-07-10'],
              dtype='datetime64[ns]', freq='D')
pd.date_range('2015-07-03',periods=8,freq='H')
DatetimeIndex(['2015-07-03 00:00:00', '2015-07-03 01:00:00',
               '2015-07-03 02:00:00', '2015-07-03 03:00:00',
               '2015-07-03 04:00:00', '2015-07-03 05:00:00',
               '2015-07-03 06:00:00', '2015-07-03 07:00:00'],
              dtype='datetime64[ns]', freq='H')
pd.period_range('2015-07-03',periods=8,freq='M')
PeriodIndex(['2015-07', '2015-08', '2015-09', '2015-10', '2015-11', '2015-12',
             '2016-01', '2016-02'],
            dtype='period[M]', freq='M')
pd.timedelta_range(0,periods=10,freq='H')
TimedeltaIndex(['00:00:00', '01:00:00', '02:00:00', '03:00:00', '04:00:00',
                '05:00:00', '06:00:00', '07:00:00', '08:00:00', '09:00:00'],
               dtype='timedelta64[ns]', freq='H')

3.12.4時間周波数とオフセット量
Pandas周波数コード
コード#コード#
説明
D
ああ
W

M
月末
Q
シーズン末
A
年末
H
時間
T

S

L
ミリ秒
U
マイクロ秒
N
ナノ秒
B
日(平日のみ)
BM
月末(平日のみ)
BQ
四半期末(平日のみ)
BA
年末(平日のみ)
BH
時間(勤務時間)
開始インデックス付き周波数コード
コード#コード#
説明
MS
月の初め
BMS
月初め(平日のみ)
QS
シーズン初め
BQS
四半期初め(平日のみ)
AS
年初
BAS
年初(平日のみ)
pd.timedelta_range(0,periods=9,freq='2H30T')
TimedeltaIndex(['00:00:00', '02:30:00', '05:00:00', '07:30:00', '10:00:00',
                '12:30:00', '15:00:00', '17:30:00', '20:00:00'],
               dtype='timedelta64[ns]', freq='150T')
from pandas.tseries.offsets import BDay
pd.date_range('2015-07-01',periods=5,freq=BDay())
DatetimeIndex(['2015-07-01', '2015-07-02', '2015-07-03', '2015-07-06',
               '2015-07-07'],
              dtype='datetime64[ns]', freq='B')

3.12.5再サンプリング、移行、およびウィンドウ
conda install pandas_datareader
from pandas_datareader import data
goog = data.DataReader('GOOG',start='2004', end='2016',
                      data_source='google')
goog.head()
  File "", line 1
    conda install pandas_datareader
                ^
SyntaxError: invalid syntax

3.12.6より多くの学習資料
3.12.7ケース:アメリカシアトル自転車統計データの可視化
3.13高性能Pandas:eval()とquery()
3.13.2 Pandas.eval()高性能演算を実現
Pandasのeval()関数は文字列代数でDataFrameの高性能演算を実現しており、例えば次のDataFrame
import pandas as pd
import numpy as np
rng = np.random.RandomState(42)
nrows, ncols = 100000,100
df1, df2, df3, df4 = (pd.DataFrame(rng.rand(nrows, ncols))
                     for i in range(4))
#     4 DataFrame  
%timeit df1 + df2 + df3 + df4
158 ms ± 2.56 ms per loop (mean ± std. dev. of 7 runs, 10 loops each)
#     pd.eval         
%timeit pd.eval('df1 + df2 + df3 + df4')
68.4 ms ± 1.18 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)

pd.eval()がサポートする演算
df1, df2, df3, df4, df5 = (pd.DataFrame(rng.randint(0, 1000,(100,3)))
                     for i in range(5))

1算術演算子
result1 = -df1 * df2 / (df3 + df4) - df5
result2 = pd.eval('-df1 * df2 / (df3 + df4) - df5')
np.allclose(result1,result2)
True

比較演算子
result1 = (df1 < df2) & (df2 <= df3) & (df3 != df4)
reuslt2 = pd.eval('df1 < df2 <= df3 != df4')
np.allclose(result1,result2)
False

ビット演算子
result1 = (df1 < 0.5) & (df2 < 0.5) | (df3 < df4)
reuslt2 = pd.eval('(df1 < 0.5) & (df2 < 0.5) | (df3 < df4)')
np.allclose(result1,result2)
False

その他の演算:pd.eval()は、関数呼び出し、条件文、ループ、およびより責任のある演算をサポートしていません.これらの演算を行うには、Numexprにより実現することができる.
3.13.3 DataFrameを使用する.eval()実装カラム間演算
pd.eval()はPandasの最上位関数であるため、DataFrameにはeval()の方法がある.eval()メソッドを使用する利点は、カラム名で演算できることです.
df = pd.DataFrame(rng.rand(1000,3),columns=['a','b','c'])
df.head()

a
b
c
0
0.375506
0.406939
0.069938
1
0.069087
0.235615
0.154374
2
0.677945
0.433839
0.652324
3
0.264038
0.808055
0.347197
4
0.589161
0.252418
0.557789
result3 = df.eval('(a + b) / (c - 1)')

DataFrameでeval()新規列
df.eval('d = (a + b) /c',inplace=True)
df.head()

a
b
c
d
0
0.375506
0.406939
0.069938
11.187620
1
0.069087
0.235615
0.154374
1.973796
2
0.677945
0.433839
0.652324
1.704344
3
0.264038
0.808055
0.347197
3.087857
4
0.589161
0.252418
0.557789
1.508776
DataFrame.eval()ローカル変数の使用
column_mean = df.mean(1)
result1 = df['a'] + column_mean
result2 = df.eval('a + @column_mean')
np.allclose(result1,result2)
True

@記号は、カラム名ではなく変数名であることを示す.
3.13.4 DataFrame.query()メソッド