しがないエンジニアのブログ

技術的な内容をメモ代わりにつらつら

pandasの細かいメモ

pandasやってて地味だが便利な操作を使うことがあったのでメモ

  • Series.to_frame()で一気にDataFrame化

Seriesにはto_frame()という関数があり、すぐにDataFrame化することができる
これで他のDataFrameとmergeしたりすることができる

df = pd.Series(pd.date_range(start='2016-01-01', end='2016-12-31', freq='D', name="Time")).to_frame()
print(type(df))
print(df.head())
print(type(df.iloc[0, 0]))
print(df.iloc[0, 0])

結果

<class 'pandas.core.frame.DataFrame'>
        Time
0 2016-01-01
1 2016-01-02
2 2016-01-03
3 2016-01-04
4 2016-01-05
<class 'pandas.tslib.Timestamp'>
2016-01-01 00:00:00

これは、最初にdate_range()でDatetimeIndexを作成している
このままではDataFrameにできないので、いったんpd.Series()でSeriesにしてから、そのあとにto_frame()でDataFrameにしている

  • インデックスの振り直し

データのプロットなどをするときに、インデックスがぐちゃぐちゃだとうまくプロットできないことがあるため、
インデックスの振り直しが重要になる

import pandas as pd
import numpy as np

# df = pd.Series(pd.to_datetime(pd.date_range(start='2014-06-01', end='2016-06-19', freq='D', name="Time"))).to_frame()
df = pd.Series(pd.date_range(start='2016-01-01', end='2016-12-31', freq='D', name="Time")).to_frame()
df2 = pd.Series(pd.date_range(start='2016-08-01', end='2016-12-31', freq='M', name="Time")).to_frame()
df = df.reindex(np.random.permutation(df.index))
df2 = df2.reindex(np.random.permutation(df2.index))

print "df\n", df.head()
print "df2\n", df2

df3 = pd.merge(df, df2, left_on="Time", right_on="Time", how="right")
print "merged\n", df3

df4 = df3.sort_values(by="Time")
print "sort_values\n", df4

df5 = df4.reset_index()
print "reset_index\n", df5

df6 = df5.drop("index", axis=1)
print "drop\n", df6

結果

df
          Time
270 2016-09-27
150 2016-05-30
300 2016-10-27
207 2016-07-26
64  2016-03-05
df2
        Time
0 2016-08-31
4 2016-12-31
2 2016-10-31
3 2016-11-30
1 2016-09-30
merged
        Time
0 2016-11-30
1 2016-10-31
2 2016-09-30
3 2016-12-31
4 2016-08-31
sort_values
        Time
4 2016-08-31
2 2016-09-30
1 2016-10-31
0 2016-11-30
3 2016-12-31
reset_index
   index       Time
0      4 2016-08-31
1      2 2016-09-30
2      1 2016-10-31
3      0 2016-11-30
4      3 2016-12-31
drop
        Time
0 2016-08-31
1 2016-09-30
2 2016-10-31
3 2016-11-30
4 2016-12-31

色々やっているが、重要な部分をまとめると
df = df.reset_index().drop("index", axis=1)である
reset_index()でインデックスを振り直すと、元のはindexというカラムができ、そちらに割り当てられる
それをdrop()すれば、順番通りに並んだindexを振りなおすことができる

  • インデックスにないデータの抽出

データを学習とテストなどに分けたい場合に、以下の方法が1行で書けるため便利

import pandas as pd
import numpy as np

df = pd.Series(pd.date_range(start='2016-01-01', end='2016-12-31', freq='M', name="Time")).to_frame()
df = df.reindex(np.random.permutation(df.index))

df_1 = df[:5]
df_2 = df.loc[~df.index.isin(df_1.index)]

print df_1
print df_2

結果

        Time
0 2016-01-31
1 2016-02-29
6 2016-07-31
5 2016-06-30
4 2016-05-31
         Time
7  2016-08-31
2  2016-03-31
11 2016-12-31
3  2016-04-30
10 2016-11-30
8  2016-09-30
9  2016-10-31

df.loc[~df.index.isin(df_1.index)]について、~は除くという意味
後ろの式は、index.isin()で、含まれるデータを抽出しているため、
含まれるデータを除くという意味になる

今後増え次第随時追記したいと思う