行の追加
空のデータフレームに行を追加
カラム名を後で設定するか、初めに設定するかで追加の手順が変わります。
多分ですが、前者の方が処理速度は早いと思います。
カラム名もないデータフレームに追加
df = df.append(リスト型データ, ignore_index=True)
append
で空のデータフレームに追加して代入します。- その後、必要に応じてカラム名を設定します。
df.columns = columns
columns = ["aaa", "bbb", "ccc"] df = pd.DataFrame() print(df) # Empty DataFrame # Columns: [] # Index: [] df = df.append([[1,2,3],[4,5,6]], ignore_index=True) df.columns = columns print(df) # aaa bbb ccc # 0 1 2 3 # 1 4 5 6
カラム名だけあるデータフレームに追加
- 追加するデータで新規にデータフレームを作成します。
df2 = pd.DataFrame(リスト型データ columns=columns)
append
で新たなデータフレームを追加して代入します。df = df.append(新たなデータフレーム, ignore_index=True)
columns = ["aaa", "bbb", "ccc"] df = pd.DataFrame(columns = columns) print(df) # Empty DataFrame # Columns: [aaa, bbb, ccc] # Index: [] df2 = pd.DataFrame([[1,2,3],[4,5,6]], columns=columns) df = df.append(df2, ignore_index=True) print(df) # aaa bbb ccc # 0 1 2 3 # 1 4 5 6
行の末尾に追加
行名を指定して
at
を用いて新規の行ラベル(インデックス)のみを指定し、リスト型またはタプル型の値を代入します。
df = pd.DataFrame([[1,2,3],[4,5,6]], columns = ["aaa", "bbb", "ccc"], index = ["val1", "val2"]) # ラベルで指定 df.at['val3'] = [7, 8, 9] print(df) # aaa bbb ccc # val1 1.0 2.0 3.0 # val2 4.0 5.0 6.0 # val3 7.0 8.0 9.0
loc
、iloc
でも取得できます。行名を指定しない
df = pd.DataFrame([[1,2,3],[4,5,6]], columns = ["aaa", "bbb", "ccc"]) print(df) # aaa bbb ccc # 0 1 2 3 # 1 4 5 6 print(df.append({"aaa": 7, "bbb": 8, "ccc": 9}, ignore_index=True)) # aaa bbb ccc # 0 1 2 3 # 1 4 5 6 # 2 7 8 9
行の先頭に追加
行の指定の位置に追加(挿入)
Pandasはデータベースの考え方に似ていますので、最後尾に追加後に、インデックスを用いてソートで表示順を指定する方法があります。
列の追加
列の末尾に追加
df = pd.DataFrame([[1,2,3],[4,5,6]], columns = ["aaa", "bbb", "ccc"], index = ["val1", "val2"]) print(df) # aaa bbb ccc # val1 1 2 3 # val2 4 5 6 # ラベルで指定 df['ddd'] = [7, 8] print(df) # aaa bbb ccc ddd # val1 1 2 3 7 # val2 4 5 6 8
列の先頭、または任意の位置に追加
df.insert(列の位置, 追加する新しいカラム名, 値)
で追加できます。
df = pd.DataFrame([[1,2,3],[4,5,6]], columns = ["aaa", "bbb", "ccc"], index = ["val1", "val2"]) print(df) # aaa bbb ccc # val1 1 2 3 # val2 4 5 6 # ラベルで指定 df.insert(0, 'ddd', [7, 8]) print(df) # aaa bbb ccc ddd # val1 1 2 3 7 # val2 4 5 6 8
別の列の値をずらして追加
このずらして追加は投資やディープラーニングでよく使います。例えばループで、毎回、前の行の値を取得するより、予め前の行の値を別の列に追加しておいた方が処理速度が格段に速くなります。
df.カラム名.shift(数値)
数値はデフォルトが1で1つ下にずれます。−1の場合は1つ上にずれます。
df = pd.DataFrame([[1,2,3],[4,5,6],[7, 8, 9]], columns = ["aaa", "bbb", "ccc"]) print(df) # aaa bbb ccc # 0 1 2 3 # 1 4 5 6 # 2 7 8 9 df["ddd"] = df.ccc.shift() print(df) # aaa bbb ccc ddd # 0 1 2 3 NaN # 1 4 5 6 3.0 # 2 7 8 9 6.0 df["ddd"] = df.ccc.shift(-1) print(df) # aaa bbb ccc ddd # 0 1 2 3 6.0 # 1 4 5 6 9.0 # 2 7 8 9 NaN
期間などの複数行の最大値などの値の列を追加
rolling(x).max()
を使用します。
- xに対象となる行数を入力します。
- 対象には自身の行も含まれます。
- xにマイナスを指定することはできません。列を追加後にshift()するといいです。
max
以外に、min
、count
、mean
、median
などを利用できます。
以下の公式サイトを参照してください。Window — pandas 2.2.2 documentationidxmax()
は使用できません。- それ以外に独自の関数を作成することが可能です。次の項目を確認してください。
import pandas as pd df = pd.DataFrame([[1,2,3],[4,5,6],[7,8,9]], columns = ["aaa", "bbb", "ccc"]) # リスト型のデータで作成 print(df) # aaa bbb ccc # 0 1 2 3 # 1 4 5 6 # 2 7 8 9 print(df["ccc"].max()) print(df["ccc"].idxmax()) df["ddd"] = df["ccc"].rolling(2).max() print(df) # aaa bbb ccc ddd # 0 1 2 3 NaN # 1 4 5 6 6.0 # 2 7 8 9 9.0
rollingで独自の関数を使用する
rolling(x).apply(y)
を使用します。
- xは同様にローリングする行数です。
- yに独自に作成した関数名を設定します。
import pandas as pd df = pd.DataFrame([[1,2,3],[4,5,6],[7,8,9]], columns = ["aaa", "bbb", "ccc"]) # リスト型のデータで作成 print(df) # aaa bbb ccc # 0 1 2 3 # 1 4 5 6 # 2 7 8 9 def x(n): return n.sum()*2 df["eee"] = df["ccc"].rolling(2).apply(x) print(df) # aaa bbb ccc ddd eee # 0 1 2 3 NaN NaN # 1 4 5 6 6.0 18.0 # 2 7 8 9 9.0 30.0
条件式で個別の値を列に追加
これも投資やディープラーニングでよく使います。ディープラーニングではしきい値を丸めたり正解ラベルを作成したりと、とっても便利です。
特に新しい関数はないのですが、ポイントは2つあります。
df.loc[条件式, 新しいカラム名] = 挿入する値
これで条件に応じて、挿入する値を振り分けることができます。
- 条件式のところで、
~
を使うと、その条件を除くという意味になります。わざわざ逆の条件式を書かなくて良いです。
今回は2つだけですが、いくつでも作ることができます。条件に満たない場合は、nan
になります。
df = pd.DataFrame([[1,2,3],[4,5,6],[7, 8, 9]], columns = ["aaa", "bbb", "ccc"]) print(df) # aaa bbb ccc # 0 1 2 3 # 1 4 5 6 # 2 7 8 9 mask = df['aaa'] > 1 column_name = 'ddd' df.loc[mask, column_name] = 1 df.loc[~mask, column_name] = 0 print(df) # aaa bbb ccc ddd # 0 1 2 3 0.0 # 1 4 5 6 1.0 # 2 7 8 9 1.0
日時データの列から年月日、曜日などの列を追加
基本
df = pd.DataFrame([["2020/05/01 12:34:56",1,True],["2020/05/01 16:34:56",4,False]], columns = ["Date Time", "bbb", "ccc"]) # リスト型のデータで作成 df['Date Time'] = pd.to_datetime(df['Date Time']) print(df) # Date Time bbb ccc # 0 2020-05-01 12:34:56 1 True # 1 2020-05-01 16:34:56 4 False df['week'] = df['Date Time'].dt.weekday_name print(df) # Date Time bbb ccc week # 0 2020-05-01 12:34:56 1 True Friday # 1 2020-05-01 16:34:56 4 False Friday
dt
はPandasのdtです。datetime
ではありません。元データは日時型でないとダメです。他にも以下を指定できます。
年月日(
year
, month
, day
)時分秒(
hour
, minute
, second
)曜日(文字列:
weekday_name
, 数値: dayofweek
)他の方法
例えば「Friday」ではなく「Fri」としたい場合は以下のようにフォーマットを指定します。
また年月などの組み合わせも簡単に指定できます。
df = pd.DataFrame([["2020/05/01 12:34:56",1,True],["2020/05/01 16:34:56",4,False]], columns = ["Date Time", "bbb", "ccc"]) # リスト型のデータで作成 df['Date Time'] = pd.to_datetime(df['Date Time']) print(df) # Date Time bbb ccc # 0 2020-05-01 12:34:56 1 True # 1 2020-05-01 16:34:56 4 False df['week'] = df['Date Time'].dt.strftime('%a') print(df) # Date Time bbb ccc week # 0 2020-05-01 12:34:56 1 True Fri # 1 2020-05-01 16:34:56 4 False Fri
dt
はPandasのdtです。datetime
ではありません。元データは日時型でないとダメです。その他にも年月日などの列を作ることができます。フォーマットは以下のドキュメントを参照してください。
削除
任意の列を削除
drop
とdel
の二通りの方法がありますが、列の削除は、del
の方が簡単で覚えやすいと思います。
df = pd.DataFrame([[1,2,3],[4,5,6]], columns = ["aaa", "bbb", "ccc"]) print(df) # aaa bbb ccc # 0 1 2 3 # 1 4 5 6 # カラム名で指定 df = df.drop("bbb", axis = 1) print(df) # aaa ccc # 0 1 3 # 1 4 6 del df["ccc"] print(df) # aaa # 0 1 # 1 4
axis = 1
と指定してください。df = df.drop(カラム名, axis = 1)
もしくは
inplace=True
と指定すれば代入は不要になりますが、覚える必要はないでしょう。列番号でも指定できますが、列番号で指定できるのはカラム名が設定されていない場合のみです。任意の行を削除
df = pd.DataFrame([[1,2,3],[4,5,6]], columns = ["aaa", "bbb", "ccc"], index = ["val1", "val2"]) # インデックス(ラベル)で指定 df = df.drop("val1") print(df) # aaa bbb ccc # val2 4 5 6 df = pd.DataFrame([[1,2,3],[4,5,6]], columns = ["aaa", "bbb", "ccc"]) # 行番で指定 df = df.drop(0) print(df) # aaa bbb ccc # 1 4 5 6
もしくは
inplace=True
と指定すれば代入は不要になりますが、覚える必要はないでしょう。行番で指定できるのはインデックスが設定されていない場合のみ、列番号で指定できるのはカラム名が設定されていない場合のみです。
日付を指定して削除
df = pd.DataFrame([["2020/05/01",1,True],["2020/05/02",4,False]], columns = ["Date Time", "bbb", "ccc"]) df.index = pd.DatetimeIndex(pd.to_datetime(df['Date Time']), name='Date Time') del df["Date Time"] print(df.drop(pd.to_datetime("2020-05-01"))) # Date Time # 2020-05-02 4 False
上記は日時データに対しては使用できません。
その場合は以下で対応しています。(他に方法があるかもしれませんが。。
# bbb ccc # Date Time # 2020-05-01 12:34:56 1 True # 2020-05-02 16:34:56 4 False import datetime as dt df['days'] = df.index df['days'] = df.days.dt.strftime('%m-%d') df = df[df['days'] != "05-01"] del df['days'] print(df) # Date Time # 2020-05-02 16:34:56 4 False
import datetime as dt
を忘れないようにしましょう。
上記の方法では月と日を指定していますので、毎年1月1日などの削除が可能です。
すべての日曜日のデータを削除する場合は、以下のようにするといいです。
df['week'] = df['Date Time'].dt.strftime('%a') df = df[df['week'] != "Sun"]
日付のその他の書式化コードはドキュメントを参照してください。
https://docs.python.org/ja/3.6/library/datetime.html#strftime-and-strptime-behavior
任意の複数行・列を削除
drop
を使用します。受け渡す値をリスト形式にします。なお列を削除するdel
は複数列に対応していません。
df = pd.DataFrame([[1,2,3],[4,5,6],[7,8,9]], columns = ["aaa", "bbb", "ccc"], index = ["val1", "val2", "val3"]) # ラベルで指定 df = df.drop(["val1", "val2"]) print(df) # aaa bbb ccc # val3 7 8 9 df = pd.DataFrame([[1,2,3],[4,5,6],[7,8,9]], columns = ["aaa", "bbb", "ccc"]) # リスト型のデータで作成 # 行番で指定 df = df.drop([0, 1]) print(df) # aaa bbb ccc # 2 7 8 9
列を削除する場合は、第二引数にaxis = 1
と指定してください。
範囲指定で行を削除
df = pd.DataFrame([[1,2,3],[4,None,6],[None,None,None],[7,8,9]], columns = ["aaa", "bbb", "ccc"]) df = df.drop(range(1, 3)) print(df) # aaa bbb ccc # 0 1.0 2.0 3.0 # 3 7.0 8.0 9.0
最後の行を削除
特に方法がありませんので、スライスを使用しましょう。
df = pd.DataFrame([[1,2,3],[4,5,6],[7,8,9]], columns = ["aaa", "bbb", "ccc"], index = ["val1", "val2", "val3"]) df = df[:-1] print(df) # aaa bbb ccc # val1 1 2 3 # val2 4 5 6 df = pd.DataFrame([[1,2,3],[4,5,6],[7,8,9]], columns = ["aaa", "bbb", "ccc"]) # リスト型のデータで作成 df = df[:-1] print(df) # aaa bbb ccc # val1 1 2 3 # val2 4 5 6
df = df[1:]
とすれば削除できます。その方が便利な時が多いです。条件による行の削除
df = pd.DataFrame([[1,2,3],[4,5,6],[None,None,None]], columns = ["aaa", "bbb", "ccc"], index = ["val1", "val2", "val3"]) df = df.drop(df[(df.aaa == 1)].index) print(df) # aaa bbb ccc # val2 4.0 5.0 6.0 # val3 NaN NaN NaN
少しデータベースっぽくなってきましたね。
・
&
、|
、~
を使う。・条件毎にカッコ
()
で囲む。空の値を削除
同じ条件でも空の値(Nan)は以下のようにします。
df = pd.DataFrame([[1,2,3],[4,None,6],[None,None,None]], columns = ["aaa", "bbb", "ccc"], index = ["val1", "val2", "val3"]) print(df) # aaa bbb ccc # val1 1.0 2.0 3.0 # val2 4.0 NaN 6.0 # val3 NaN NaN NaN # 列を指定 df = df.drop(df[(df.bbb.isna())].index) print(df) # aaa bbb ccc # val1 1.0 2.0 3.0 # nanが含まれる行を削除 print(df.dropna(how='any')) # aaa bbb ccc # val1 1.0 2.0 3.0 # すべての値がnanである行を削除 print(df.dropna(how='all')) # aaa bbb ccc # val1 1.0 2.0 3.0 # val2 4.0 NaN 6.0
isnull
でも同じですが、isna
のエイリアスなのです。行や列の順序を入れ替え
df.reindex
で行や列の順番を並び替えることができます。
行の順番を入れ替え
df = pd.DataFrame([[1,2,3],[4,5,6]], columns = ["aaa", "bbb", "ccc"], index = ["val1", "val2"]) print(df) # aaa bbb ccc # val1 1 2 3 # val2 4 5 6 df = df.reindex(index=["val2", "val1"]) print(df) # aaa bbb ccc # val2 4 5 6 # val1 1 2 3
列の順番を入れ替え
df = pd.DataFrame([[1,2,3],[4,5,6]], columns = ["aaa", "bbb", "ccc"], index = ["val1", "val2"]) print(df) # aaa bbb ccc # val1 1 2 3 # val2 4 5 6 df = df.reindex(columns=["ccc", "aaa", "bbb"]) print(df) # ccc aaa bbb # val1 3 1 2 # val2 6 4 5
コメント