概要
翔泳社「現場で使える!pandasデータ前処理入門 機械学習・データサイエンスで役立つ前処理手法」(株式会社ロンバート著・2020年4月20日発売)を読んでpandasを勉強していますが、この本で扱っているpandasのバージョンが0.22.0と古いため、最新バージョンのpandasではサンプルコードが動かないところが多々ありました。
本記事では、執筆時点で最新のpandas2.0.3で本書と同等の実行結果を出力させるにはどのようにコードを書けばよいのかをまとめました。
※あくまで自分用のメモなので参考程度でお願いします。
※3.2.4 HDF5(P223~231)の項目は扱っていないのでご了承ください。
↑この本です。扱っているpandasのバージョンが古い点以外は内容も充実しており気に入ってます。今からpandasを学ぶ人は最近出た本を選んだ方がいいかもしれないですが…
pandas ver2対応メモ
▼リスト2.31(P79)
ser2 = pd.Series([5, 6], index=['い','う'])
# ser.append(ser2)
pd.concat([ser,ser2], axis=0)
Series.append は v1.4 で非推奨になり、v2で削除されました。
代わりにconcatを使用しましょう。
なお、axis=0は省略可能です。
append→concatは今後もかなり出てきます。毎回説明しているとキリがないので次以降は説明省略します。
▼リスト2.32(P80)
# ser.append(ser2, ignore_index=True)
pd.concat([ser,ser2], axis=0, ignore_index=True)
▼リスト2.64(P100)
val = [7,8,9,10,11]
idx = [0,1,2,'new1','new2']
series_add = pd.Series(val, index=idx, name='new3')
# df = df.append(series_add)
df = pd.concat([df,series_add.to_frame().T], axis=0)
df
▼リスト2.78(P110)
idx1 = pd.Index([1,7,2,3,5])
idx2 = pd.Index([3,4,1,5,6])
# print(idx1 & idx2)
# print(idx1 | idx2)
print(idx1.intersection(idx2))
print(idx1.union(idx2))
&の代わりにintersection、|の代わりにunionを使用します。&や|を使用してもエラーにはなりませんが、意図した実行結果になりません。
▼リスト2.83(P112)
# idx_date = pd.DatetimeIndex(
idx_date = pd.date_range(
freq='D',
start='2018-12-28',
end='2019-01-05'
)
idx_date
pd.DatetimeIndexの代わりにpd.date_rangeを使用します。引数は同じで大丈夫です。
▼リスト2.85(P113)
# df_date['2019']
df_date.loc['2019']
上だとKeyErrorで怒られます。locを使えば大丈夫なようです。
▼リスト2.124(P138)
grouped = df.groupby('sex')
# grouped.mean()
grouped.mean(numeric_only=True)
numeric_only引数をTrueにすると、要素が数値型のカラムのみが対象になります。
v1まではnumeric_only=Trueがデフォルトなので省略可能でしたが、v2ではnumeric_only=Falseがデフォルトになったので明示的に指定しないとエラーになります。
numeric_only=Trueもappend→concat同様多く登場します。毎回説明しているとキリがないので次回以降は説明省略します。
▼リスト3.54(P184)
# pd.read_csv('../data/ex2.csv', usecols=['weight'], squeeze=True)
pd.read_csv('../data/ex2.csv', usecols=['weight']).squeeze()
squeeze引数はv1.5で非推奨になり、v2で削除されたようです。
代わりにpandas.DataFrame.squeezeを使用します。
▼リスト3.73(P197)
pd.read_csv('../data/ex5.csv',
# error_bad_lines=False,
# warn_bad_lines=True)
on_bad_lines='warn')
error_bad_linesとwarn_bad_linesはv1.3で非推奨となり、v2で削除されたようです。
代わりにon_bad_lines引数を使用します。
▼リスト3.77(P199)
# pd.read_csv('../data/ex7.csv', mangle_dupe_cols=True)
pd.read_csv('../data/ex7.csv')
mangle_dupe_cols引数はv1.5時点で非推奨となり、v2で削除されたようです。
v2ではそのまま読み込めば大丈夫なようです。
▼リスト4.48(P266)
# pd.pivot_table(df, index='sex', aggfunc=np.mean)
pd.pivot_table(df, index='sex', aggfunc=np.mean, values=['art','eng','hist','math','scie'])
values引数を指定します。
▼リスト5.6(P289)
# df.append(df2)
pd.concat([df,df2])
▼リスト5.7(P290)
# df.append(df2, ignore_index=True)
pd.concat([df,df2], ignore_index=True)
▼リスト5.8(P290)
df3 = pd.DataFrame([[7,8,9]],columns=['a','b','c'])
# df.append(df3)
pd.concat([df,df3])
▼リスト5.25(P302)
# pd.concat([df1,dft], axis=1, join_axes=[df1.index])
pd.concat([df1,dft], axis=1).loc[df1.index,:]
▼リスト5.28(P304)
# df1.append(df2)
pd.concat([df1,df2],axis=0)
▼リスト5.29(P305)
# df1.append(df2, ignore_index=True)
pd.concat([df1,df2], axis=0, ignore_index=True)
▼リスト5.30(P305)
dft = df2.copy()
dft.columns = ['a','b','d']
# df1.append(dft.loc[0,:])
pd.concat([df1,dft.loc[0,:].to_frame().T], axis=0)
▼リスト5.31(P306)
ser1 = pd.Series(['s1','s2','s3'])
ser2 = pd.Series(['s4','s5','s6'])
# ser1.append(ser2)
pd.concat([ser1,ser2], axis=0)
▼リスト5.32(P307)
ser1.index = ['a','b','c']
ser1.name = 'ser1'
# df1.append(ser1)
pd.concat([df1,ser1.to_frame().T], axis=0)
▼リスト5.36(P313)
ser1 = pd.Series(['a3','b3','left_k3'],index=['a','b','key'])
# leftdf = leftdf.append(ser1, ignore_index=True)
leftdf = pd.concat([leftdf,ser1.to_frame().T], axis=0, ignore_index=True)
leftdf
ser2 = pd.Series(['c3','d3','right_k3'],index=['c','d','key'])
# rightdf = rightdf.append(ser2, ignore_index=True)
rightdf = pd.concat([rightdf,ser2.to_frame().T], axis=0, ignore_index=True)
rightdf
▼リスト7.33(P407)
# for idx, val in ser.iteritems():
for idx, val in ser.items():
print(idx, val)
▼リスト7.34(P408)
# for idx, val in ser.iteritems():
for idx, val in ser.items():
if val < 3:
print(idx)
▼リスト7.44(P414)
# for col, val in df.iteritems():
for col, val in df.items():
print(col)
print(val, '\n')
▼リスト7.45(P415)
# for col, val in df.iteritems():
for col, val in df.items():
mean = val.mean()
print(col, 'の平均点は', mean)
▼リスト7.56(P423)
# grouped.mean()
grouped.mean(numeric_only=True)
▼リスト7.60(P425)
grouped = df.groupby(['sex','club'])
# grouped.mean()
grouped.mean(numeric_only=True)
▼リスト7.61(P426)
grouped = df.groupby(['sex','club'], as_index=False)
# grouped.mean()
grouped.mean(numeric_only=True)
▼リスト7.65(P428)
# df2.groupby(by='club').mean()
df2.groupby(by='club').mean(numeric_only=True)
▼リスト7.66(P428)
# df2.groupby(level=0).mean()
df2.groupby(level=0).mean(numeric_only=True)
▼リスト7.75(P433)
grouped = df.groupby('sex')
# grouped.mean()
grouped.mean(numeric_only=True)
# grouped.agg('mean')
grouped.agg('mean', numeric_only=True)
▼リスト7.76(P434)
# grouped.agg(np.mean)
grouped[['math','eng','scie']].agg(np.mean)
▼リスト7.80(P436)
# grouped.agg(max_min)
grouped[['math','eng','scie']].agg(max_min)
▼リスト7.81(P437)
# df.groupby(['sex','club']).agg(['mean','sum'])['math']
df.groupby(['sex','club'])[['math','eng','scie']].agg(['mean','sum'])['math']
▼リスト7.85(P439)
df2 = df.copy()
# df2['カテゴリ別平均'] = grouped.transform(lambda x: x.mean())
df2['カテゴリ別平均'] = grouped['sales'].transform(lambda x: x.mean())
df2
▼リスト7.86(P440)
# df2['万'] = grouped.transform(lambda x: x / 10000)
df2['万'] = grouped['sales'].transform(lambda x: x / 10000)
df2
▼リスト7.87(P441)
df2 = df.copy()
# cat_total = df2.groupby('category').sum()
cat_total = df2.groupby('category')[['sales']].sum()
cat_total.columns = ['cat_total']
cat_total
▼リスト7.91(P444)
# %timeit df.groupby('sex').apply(lambda x: x.mean())
# %timeit df.groupby('sex').mean()
%timeit df.groupby('sex')[['math','eng','scie']].apply(lambda x: x.mean())
%timeit df.groupby('sex').mean(numeric_only=True)
▼リスト7.97(P448)
# mean = round(df2.mean())
mean = round(df2.mean(numeric_only=True))
mean
▼リスト7.98(P448)
# df2.groupby('club').mean()
df2.groupby('club').mean(numeric_only=True)
▼リスト7.99(P449)
grouped = df2.groupby('club')
# grouped.apply(lambda x: x.fillna(x.mean()))
grouped.apply(lambda x: x.fillna(x.mean(numeric_only=True)))
▼リスト8.20(P463)
# df['class'] = df['class'].str.replace(pat=pattern, repl='')
df['class'] = df['class'].str.replace(pat=pattern, repl='', regex=True)
df
▼リスト8.75(P506)
# midx.labels
midx.codes
▼リスト8.94(P518)
# df.index.is_lexsorted()
# df.sort_index(level=0).index.is_lexsorted()
index.is_lexsortedは廃止されたようです。代替手段は不明です。
▼リスト8.101(P522)
df.loc[[('Sapporo','M','Marketing'),
# ('Sapporo','F','Marketing'),
('Tokyo','F','Marketing'),]]
現在のバージョンでは、インデックスラベルに含まれていない場合はKeyErrorを返すようです。
▼リスト8.109(P526)
print(df2.index.levels[0])
# print(df2.index.labels[0])
print(df2.index.codes[0])
df2
▼リスト8.110(P527)
# df2.index = df2.index.set_labels(labels=[1,1,1,0,0,2,2],
df2.index = df2.index.set_codes(codes=[1,1,1,0,0,2,2],
level=0)
df2
▼リスト8.116(P531)
# df['age'].mean(axis=0, level='address')
df['age'].groupby('address').mean()
▼リスト8.117(P531)
# df['age'].mean(axis=0, level=['address','sex'])
df['age'].groupby(['address','sex']).mean()
▼リスト8.118(P532)
# df.mean(level='sex')
DataFrame.mean()のlevel引数は削除されたっぽいです。同ページに記載されているgroupbyメソッドのやり方を使用しましょう。
▼リスト8.143(P547)
# ts.week, ts.dayofweek, ts.weekday_name
ts.week, ts.dayofweek, ts.day_name()
▼リスト8.150(P550)
# pd.DatetimeIndex(start='20190101', end='20190105', freq='D')
pd.date_range(start='20190101', end='20190105', freq='D')
▼リスト8.151(P551)
# pd.DatetimeIndex(start='20190101', periods=5, freq='W-SUN')
pd.date_range(start='20190101', periods=5, freq='W-SUN')
▼リスト8.164(P557)
# pd.PeriodIndex(start='2019-Apr', periods=5, freq='M')
pd.period_range(start='2019-Apr', periods=5, freq='M')
▼リスト8.168(P559)
# pd.DatetimeIndex(start='20190501 17:00', periods=5, freq='H')
pd.date_range(start='20190501 17:00', periods=5, freq='H')
from pandas.tseries.offsets import Hour
# pd.DatetimeIndex(start='20190501 17:00', periods=5, freq=Hour())
pd.date_range(start='20190501 17:00', periods=5, freq=Hour())
▼リスト8.170(P560)
# pd.DatetimeIndex(start='20190501 17:00', periods=5, freq=5 * Hour())
pd.date_range(start='20190501 17:00', periods=5, freq=5 * Hour())
▼リスト8.171(P561)
# pd.DatetimeIndex(start='20190501 17:00', periods=5, freq='5H')
pd.date_range(start='20190501 17:00', periods=5, freq='5H')
▼リスト8.172(P561)
# pd.DatetimeIndex(start='20190501 17:00', periods=5, freq=hours_minutes)
pd.date_range(start='20190501 17:00', periods=5, freq=hours_minutes)
▼リスト8.173(P562)
# pd.DatetimeIndex(start='20190501 17:00', periods=5, freq='3h20min')
pd.date_range(start='20190501 17:00', periods=5, freq='3h20min')
▼リスト8.174(P562)
# pd.DatetimeIndex(start='20110501', periods=2, freq='A-DEC')
pd.date_range(start='20110501', periods=2, freq='A-DEC')
from pandas.tseries.offsets import YearEnd
# pd.DatetimeIndex(start='20110501', periods=2, freq=YearEnd())
pd.date_range(start='20110501', periods=2, freq=YearEnd())
▼リスト8.175(P563)
# pd.DatetimeIndex(start='20110501', periods=2, freq='AS-JAN')
pd.date_range(start='20110501', periods=2, freq='AS-JAN')
from pandas.tseries.offsets import YearBegin
# pd.DatetimeIndex(start='20110501', periods=2, freq=YearBegin())
pd.date_range(start='20110501', periods=2, freq=YearBegin())
▼リスト8.179(P567)
# ser[datetime.date(2019,1,2)]
これはKeyErrorになります。代替手段は不明です。
▼リスト8.185(P570)
# df['2018-12-31 23']
df.loc['2018-12-31 23']
▼リスト8.190(P573)
# ser.tshift(-2)
Series.tshiftは廃止されたぽいです。リスト8.191の方法を使いましょう。
▼リスト9.22(P601)
# df.corr().style.background_gradient(cmap='coolwarm')
df.corr(numeric_only=True).style.background_gradient(cmap='coolwarm')
▼リスト9.29(P611)
# df.groupby('年代').sum()
df.groupby('年代').sum(numeric_only=True)
▼リスト9.101(P661)
time['Year'] = time.index.year
time['Month'] = time.index.month
time['Day'] = time.index.day
# time['Weekday'] = time.index.weekday_name
time['Weekday'] = time.index.day_name()
time['Hour'] = time.index.hour
time.head(3)
参考文献
pandas documentation — pandas 2.0.3 documentation
【保存版】Pandas2.0のread_csv関数の全引数、パフォーマンス、活用テクニックを完全解説する! - Qiita