とほほのPandas 3入門
目次
- Pandasとは
- リンク
- 環境
- 準備
- Series・DataFrameを作成する
- 列の型
- DataFrameをファイルから読み込む
- CSV, TSV, TXT, JSON, Excel, HTML から読み込む(read_csv(), read_json(), read_excel(), read_html())
- セパレーターを指定する(TSV,TXTファイル対応)(sep)
- 列ラベルを指定する(header, names)
- 行ラベルを指定する(index_col)
- 指定した列のみを読み込む(usecols)
- 指定した行を読み飛ばす(skiprows, skipfooter)
- 指定した行数分読み込む(nrows)
- 列の型を指定する(dtype)
- 日付フォーマットを指定する(parse_dates, date_format)
- 欠損値を指定する(na_values, keep_default_na, na_filter)
- 圧縮ファイルを読み込む(compression)
- エンコーディングを指定する(encoding, encoding_errors)
- DataFrameをファイルに書き込む
- DataFrame情報を得る
- DataFrameから行・列を取り出す
- DataFrameに行・列を追加する
- 列・行を削除する
- 欠損値
- マルチインデックス
- DataFrameをソートする
- DataFrameをマージする
- DataFrameをグルーピングする
- ラベルを変更する
- データに対して関数を実行する
- ループで回す
- 集計や変更
- その他
Pandasとは
- Python で Excel の様な2次元のデータを高速に扱うことができるライブラリです。
- データ解析、数値計算、統計、最近では AI の機械学習などに利用されます。
- BSD ライセンスで提供され、商用でも無償利用可能です。
- パネルデータ(PANel DAta)が名前の由来です。
- 1次元の シリーズ(Series) オブジェクトと、2次元の データフレーム(DataFrame) オブジェクトをサポートします。
- 2026年1月21日に Pandas 3 がリリースされました。現時点(2026年2月15日)の最新版は 3.0.0 です。
- Pandas 3 では Copy-on-Write がデフォルト動作となったり、文字列型
stringが追加されました。 - 他にも Pandas 2 から破壊的な変更もいくつか行われています。
- pandas 3リリース🎉破壊的変更とv2/v3互換コードの書き方 (By @jmatsuzawaさん)
- 本書で説明する機能は Pandas の基本的な機能のみです。他にも様々なメソッドやオプションがサポートされていますので、詳細はリンク先を参照してください。
リンク
環境
本書は下記の環境で検証しています。
OS: AlmaLinux 10.1 Python: 3.12.12 Pandas: 3.0.0 Numpy: 2.4.2
準備
インストール
pip install pandas
モジュールをインポートする
pandas をインポートします。
import pandas as pd
Numpy を使用する場合は numpy もインポートしてください。
import numpy as np
Series・DataFrameを作成する
Seriesを生成する(Series())
一次元配列を引数として Series を生成します。
ser = pd.Series(['A', 'B', 'C', 'D'])
DataFrameを生成する(DataFrame())
下記の様な二次元配列を渡します。行ラベル(index)、列ラベル(columns)を省略した場合はいずれも [0, 1, 2, ...] とみなされます。
df = pd.DataFrame([
['Yamada', 36],
['Suzuki', 42],
['Tanaka', 54],
], columns=['Name', 'Age'], index=[1, 2, 3])
辞書から作成することもできます。
df = pd.DataFrame({
'Name': ['Yamada', 'Suzuki', 'Tanaka'],
'Age': [36, 42, 54]
})
辞書リストから作成することもできます。
df = pd.DataFrame([
{'Name': 'Yamada', 'Age': 36},
{'Name': 'Suzuki', 'Age': 42},
{'Name': 'Tanaka', 'Age': 54},
])
以後の説明では、基本的に下記で作成した DataFrame に対する操作で説明します。
df = pd.DataFrame({
'Name': ['Yamada', 'Suzuki', 'Tanaka'],
'Age': [36, 42, 54]
})
# Name Age
# 0 Yamada 36
# 1 Suzuki 42
# 2 Tanaka 54
列の型
Pandasで扱えるデータ型
下記などのデータ型を扱うことができます。
int8, int16, int32, int64 # NumPy由来の整数。NaNを扱えない ([-128, 127]) uint8, uint16, uint32, uint64 # NumPy由来の整数。NaNを扱えない ([0, 255]) Int8, Int16, Int32, Int64 # Pandas拡張の整数。NaNを扱える ([-128, 127, np.nan]) UInt8, UInt16, UInt32, UInt64 # Pandas拡張の非負整数。NaNを扱える ([123, 124, np.nan]) float16, float32, float64 # NumPy由来の浮動小数点数。NaNを扱える ([12.3, 12.4, np.nan]) bool # NumPy由来の真偽値。NaNを扱えない ([True, False]) boolean # Pandas拡張の真偽値。NaNを扱える ([True, False, np.nan]) object # 汎用的 ([1, 12.3, 'ABC']) string # 文字列 (['ABC', 'XYZ']) category # 列挙型(高速) ["Red", "Green", "Red"] datetime64[ns] # 日時(ナノ秒単位) ["2026-02-08 12:59:59.999999999"] timedelta64[ns] # 時間差(ナノ秒単位) (["123s", "42s"]) period # 期間 ([pd.Period("2026-02-08", freq="M")]) interval # インターバル ([pd.Interval(0, 10)]) complex64, complex128 # 複素数 ([1+1j, 2+2j]) Sparse # スパースデータ(NaNにメモリを割り当てない形式) ArrowDtype # Apache Arrow互換(pyarrow)(実験的機能)
上記の他に Python の型も指定できます。
str # 文字列(stringとほぼ同義) int # 整数(int32やint64) float # 浮動小数点数(float32やfloat64)
列の型を表示する(dtypes)
dtypes で列の型を確認することができます。
df.dtypes # Name str # Age int64 # dtype: object
列の型を変更する(astype())
列の型を変更するには astype() を使用します。
df = df.astype('string') # すべての列の型をstringに変換
df['Age'] = df['Age'].astype('UInt16') # Age列の型をUInt16に変換
DataFrameをファイルから読み込む
CSV, TSV, TXT, JSON, Excel, HTML から読み込む(read_csv(), read_json(), read_excel(), read_html())
CSV、TSV、TXT、JSON、Excel ファイルなどから読み込むことができます。
df = pd.read_csv('example.csv') # CSVファイル(1行目はヘッダー)
df = pd.read_json('example.json') # [{"Name":"...","Age":...},...]
df = pd.read_excel('example.xlsx') # Excelファイル(1行目はヘッダー)
df = pd.read_html('example.html')[0] # <table><tr><th>Name</th>...
URL から読み込むこともできます。
df = pd.read_csv('https://example.com/example.csv')
セパレーターを指定する(TSV,TXTファイル対応)(sep)
sep にセパレーターを指定することができます。
df = pd.read_csv('example.tsv', sep='\t') # TSVファイル(1行目はヘッダー)
df = pd.read_csv('example.txt', sep=r'\s+') # ホワイトスペース区切りテキスト(1行目はヘッダー)
列ラベルを指定する(header, names)
read_csv() で通常は1行目をヘッダーと見なしますが、header に None を指定するとヘッダー無しと見なします。数値を指定すると header 行目をヘッダー、次の行からをデータと見なします。
df = pd.read_csv(file, header=None) # ヘッダー無し df = pd.read_csv(file, header=0) # 0行目がヘッダー、1行目以降がデータ(0始まり) df = pd.read_csv(file, header=1) # 1行目がヘッダー、2行目以降がデータ(0始まり)
names で列ラベルを指定するとそれが優先されます。
df = pd.read_csv(file, names=['Name', 'Age']) # CSVファイルにヘッダーが無い場合 df = pd.read_csv(file, names=['Name', 'Age'], header=0) # CSVファイル0行目のヘッダーを無視する場合
行ラベルを指定する(index_col)
index_col に数値を指定すると index_col 列目を行ラベル、次の列からをデータと見なします。
df = pd.read_csv(file, index_col=0) # 0列目が行ラベル、1列目以降がデータ(0始まり) df = pd.read_csv(file, index_col=1) # 1列目が行ラベル、2列目以降がデータ(0始まり)
指定した列のみを読み込む(usecols)
usecols を指定すると読み込む列を指定できます。
df = pd.read_csv(file, usecols=[0,2,3]) # 0, 2, 3列目のみを読み込む(0始まり) df = pd.read_csv(file, usecols=['Age']) # Age列目のみを読み込む
指定した行を読み飛ばす(skiprows, skipfooter)
skiprows を指定すると指定した行数や指定した行を読み飛ばします。
df = pd.read_csv(file, skiprows=1) # 最初の1行分(1始まり)を読み飛ばす df = pd.read_csv(file, skiprows=[0,2]) # 0行目と2行目(0始まり)を読み飛ばす
skiprows にはラムダ式を与えることもできます。
df = pd.read_csv(file, skiprows=lambda x: x not in [0,2,3]) # 0行目をヘッダ、2,3行目をデータとして読み込む
skipfooter はスキップする末尾の行数を指定します。数値のみ指定できます。engine='c' の場合は使用できません。エラーが出る場合は engine='python' を指定してください。
df = pd.read_csv(file, skipfooter=100, engine='python') # 末尾の100行は読み込まない
指定した行数分読み込む(nrows)
nrows は読み込む最大データ行数を指定します。ヘッダ行はカウントしません。
df = pd.read_csv(file, nrows=10) # 10行分のデータを読む
100~199 行目のデータを読み込みたい場合は次のようにします。
df = pd.read_csv(file, skiprows=range(1,100), nrows=100) # 0行目がヘッダーの場合 df = pd.read_csv(file, header=None, skiprows=99, nrows=100) # ヘッダーが無い場合
列の型を指定する(dtype)
dtype で読み込む際の列のデータ型を指定することができます。
df = pd.read_csv(file, dtype={'Name': 'string', 'Age': 'UInt16'})
日付フォーマットを指定する(parse_dates, date_format)
parse_dates で日時として解釈して欲しい列を、date_format でその フォーマット を指定することができます。
df = pd.read_csv(file, parse_dates=['StartDate', 'EndDate'], date_format='%Y-%m-%d')
欠損値を指定する(na_values, keep_default_na, na_filter)
デフォルトでは空文字、NaN、nan、N/A、NA、null、NULL はすべて欠損値とみなします。欠損値とみなしたい文字列を追加するには na_values を指定します。
df = pd.read_csv(file, na_values=['#VALUE!', '#N/A!'])
逆に NaN のみを欠損値として扱い、他は通常の文字列として扱って欲しい場合は下記のようにします。
df = pd.read_csv(file, na_values=['NaN'], keep_default_na=False)
すべての値を欠損値として扱いたくない場合は na_filter=False を指定します。
df = pd.read_csv(file, na_filter=False)
圧縮ファイルを読み込む(compression)
read_csv() は圧縮ファイルを読み込むことができます。拡張子が .gz, .bz2, .zip, .xz, .zst, .tar, .tar.gz, .tar.xz, .tar.bz2 であれば展開アルゴリズムを自動的に判断します。複数ファイルを読むことはできません。compression には圧縮ファイルの扱い方(infer, gzip, bz2, zstd, xz, tar, None) を指定します。
df = pd.read_csv('example.csv.zip')
df = pd.read_csv('example.csv.zip', compression='infer') # 拡張子から自動判断(デフォルト)
df = pd.read_csv('example.csv.gz', compression='gzip') # .gz
df = pd.read_csv('example.csv.zip', compression=None) # 解凍しない
エンコーディングを指定する(encoding, encoding_errors)
encoding でエンコーディングを指定できます。
df = pd.read_csv(file, encoding='utf-8') df = pd.read_csv(file, encoding='Shift_JIS') df = pd.read_csv(file, encoding='ISO-2022-JP')
encoding_errors にはエンコードエラー発生時の処理を指定できます。
- strict : エラーがあると例外を投げる。
- ignore : エラーを無視する。
- replace : エラー文字を �(U+FFFD) に置換する。
- backslashreplace : エラー文字を
\xhh,\uxxxx,\Uxxxxxxxxに置換する。
df = pd.read_csv(file, encoding='Shift_JIS', encoding_errors='ignore')
DataFrameをファイルに書き込む
CSVファイルに書き込む(to_csv())
to_csv() で DataFrame を CSV ファイルに書き込むことができます。
df.to_csv('example.csv')
区切り文字を指定する(sep)
sep で区切り文字を指定できます。
df.to_csv('example.tsv', sep='\t') # TSVファイル
df.to_csv('example.txt', sep=' ') # TEXTファイル
欠損値を指定する(na_rep)
na_rep で欠損値をどのように書き出すかを指定します。デフォルトは空文字('')です。
df.to_csv(file, na_rep='NaN')
書き込む列を指定する(float_format)
float_format で浮動小数点数のフォーマットを指定できます。
df.to_csv(file, float_format='%.0f') # 整数部のみ df.to_csv(file, float_format='%.3f') # 小数以下3桁まで df.to_csv(file, float_format='%.3g') # 有効桁3桁まで df.to_csv(file, float_format='%.3e') # 小数以下3桁×指数表記
書き込む列を指定する(columns)
columns で書き込む列を指定できます。
df.to_csv(file, columns=['Name', 'Age'])
列ラベル、行ラベルの書き出しを制御する(header, index)
header、index に False を指定すると列ラベル、行ラベルを書き出しません。
df.to_csv('example.csv', header=False, index=False) # 書き出さない
df.to_csv('example.csv', header=['Name', 'Age']) # 指定したラベルで書き出す
上書き・追記モードを指定する(mode)
mode で上書き・追記モードを指定できます。
df.to_csv(file, mode='w') # 上書モード df.to_csv(file, mode='a') # 追記モード df.to_csv(file, mode='x') # ファイルが既に存在していればエラー
エンコーディングを指定する(encoding)
encoding でエンコーディングを指定できます。
df.to_csv(file, encoding='Shift_JIS') # シフトJIS
圧縮形式を指定する(compression)
ファイルに拡張子(.gz, .bz2, .zip, .xz, .zst, .tar, .tar.gz, .tar.xz, .tar.bz2)を指定すると自動的に圧縮して書き出します。
df.to_csv('example.csv.zip') # Zip圧縮
compression で明示的に指定することもできます。
df.to_csv('example.csv.zip', compression='zip')
改行コードを指定する(lineterminator)
lineterminator で改行コードを指定することができます。デフォルトは OS の標準に従います。
df.to_csv('example.csv.zip', lineterminator='\r\n')
日付フォーマットを指定する(date_format)
date_format で日付フォーマットを指定することができます。
df.to_csv(file, date_format='%Y/%m/%d')
DataFrame情報を得る
DataFrame情報を得る(info())
info() は DataFrame に関する列数、行数、型、使用メモリなどの情報を返します。
print(df.info()) # <class 'pandas.DataFrame'> # RangeIndex: 3 entries, 0 to 2 # Data columns (total 2 columns): # # Column Non-Null Count Dtype # --- ------ -------------- ----- # 0 Name 3 non-null str # 1 Age 3 non-null int64 # dtypes: int64(1), str(1) # memory usage: 180.0 bytes # None
列ラベル、行ラベル、データ型、値を得る(columns, index, dtypes, values)
列ラベル(columns)、行ラベル(index)、データ型(dtypes)、値(values) を表示します。
df = pd.DataFrame({'Name': ['Yamada', 'Suzuki', 'Tanaka'], 'Age': [36, 42, 54]})
df.columns # Index(['Name', 'Age'], dtype='str')
df.index # RangeIndex(start=0, stop=3, step=1)
df.dtypes['Name'] # str
df.values # [['Yamada', 36], ['Suzuki', 42], ['Tanaka', 54]]
列ラベル(columns)、行ラベル(index) は tolist() でリスト化できます。
df.columns.tolist() # ['Name', 'Age'] df.index.tolist() # [0, 1, 2]
行数、列数を得る(len, size, shape)
len(df) # 3 ... 行数 len(df.columns) # 2 ... 列数 df.shape # (3, 2) ... (行数, 列数) df.size # 6 ... 行数×列数
数値列の統計量を得る(describe())
describe() は数値列の個数、平均値、標準偏差、最小値、25%値、50%値(中央値)、75%値、最大値を返します。
print(df.describe()) Age count 3.000000 mean 44.000000 std 9.165151 min 36.000000 25% 39.000000 50% 42.000000 75% 48.000000 max 54.000000
DataFrameから行・列を取り出す
指定した列を取り出す([...])
列ラベルを指定して取り出します。戻り値は DataFrame ではなく Series となります。
df['Name'] # Series(['Yamada', 'Suzuki', 'Tanaka']) df.Name # Series(['Yamada', 'Suzuki', 'Tanaka'])
tolist() でリスト化できます。
df['Name'].tolist() # ['Yamada', 'Suzuki', 'Tanaka'] df.Name.tolist() # ['Yamada', 'Suzuki', 'Tanaka']
行ラベル、列ラベルを指定して取り出す(loc[], at[], filter())
行ラベルを指定して取り出します。
df.loc[2] # 2行目をSeriesとして取り出す df.loc[0:2] # 0~2行目をDataFrameとして取り出す df.loc[[0,2]] # 0と2行目をDataFrameとして取り出す
列ラベルを指定して取り出します。
df.loc[:, 'Name'] # Name列をSeriesとして取り出す df.loc[:, 'Name':'Age'] # Name列~Age列をDataFrameとして取り出す df.loc[:, ['Name', 'Age']] # Name列とAge列をDataFrameとして取り出す
行ラベル、列ラベルを用いて値を取り出します。
df.at[1, 'Name'] # 1行目のName列の値を取り出す
filter() を用いても同様のことができます。
df.filter(items=['Name', 'Age']) # 列ラベルを指定して列を取り出す df.filter(items=[0, 1, 2], axis=1) # 行ラベルを指定して行を取り出す
like はラベル名を部分マッチで、regex は正規表現でマッチさせます。
df.filter(like='ame') # ameを含む列ラベルの列を取り出す df.filter(regex=['e$']) # 末尾がeで終わる列ラベルの列を取り出す
行インデックス、列インデックスを指定して取り出す(iloc[], iat[])
行インデックス(0, 1, 2, ...)を用いて取り出します。行ラベルを index=[1, 2, 3, ...] としていても、行インデックスは 0 から始まります。
df.iloc[0] # 0行目をSeriesとして取り出す df.iloc[0:2] # 0~(2-1)行目をDataFrameとして取り出す df.iloc[[0,2]] # 0行目と2行目をDataFrameとして取り出す
列インデックス(0, 1, 2, ...)を用いて取り出します。
df.iloc[:, 0] # 0列目をSeriesとして取り出す df.iloc[:, 0:2] # 0~(2-1)列目をDataFrameとして取り出す df.iloc[:, [0,1]] # 0列目と1列目をDataFrameとして取り出す
行インデックス、列インデックスを用いて値を取り出します。
df.iat[0, 0] # 0行目の0列目の値を取り出す
最初の/最後のn行を取り出す(head(), tail())
最初の n 行、最後の n 行を取り出します。n を省略すると5と見なします。
df.head(3) # 最初の3行 df.tail(3) # 最後の3行
条件にマッチした行を取り出す([condition])
下記の様にして条件にマッチした行を取り出すことができます。AND(&) や OR(|) も使用できます。
df[df['Age'] > 40] df[(40 <= df['Age']) & (df['Age'] < 50)]
条件にマッチした行を取り出す(query())
query() を用いても同様のことができます。使用できる演算子には、等しい(==)、等しくない(!=)、大小比較(<, <=, >=, >)、四則演算(+, -, *, /)、切り捨て除算(//)、剰余(%)、べき乗(**)、含む(in)、かつ(and)、または(or)、否定(not)、ビット反転(~)などがあります。
df.query('Age > 40')
df.query('Name in ["Yamada", "Suzuki"]')
@ で変数も参照できます。
low = 40
high = 50
df2 = df.query('@low <= Age < @high')
str で文字列化することによりいくつかの文字列メソッドを使用できます(詳細)。
df.query('Name.str.contains("a")') # "a"を含んでいれば
df.query('Name.str.startswith("Y")') # "Y"で始まっていれば
df.query('Name.str.endswith("a")') # "a"で終わっていれば
df.query('Name.str.match(r"[XYZ]")') # 正規表現 [XYZ] にマッチすれば
df.query('Name.str.isalpha()') # アルファベットであれば
df.query('Name.str.isdigit()') # 数値であれば
df.query('Name.str.lower() == "yamada"') # 小文字に変換
df.query('Name.str.upper() == "YAMADA"') # 大文字に変換
df.query('Name.str.len() == 6') # 文字数
df.query('Name.str.count("a") == 3') # "a"が現れる回数
df.query('Name.str.strip() == "Yamada"') # 左右の空白を削除
df.query('Name.str.lstrip() == "Yamada"') # 左側の空白を削除
df.query('Name.str.rstrip() == "Yamada"') # 右側の空白を削除
df.query('Name.str.replace("Y", "T") == "Tamada"') # "Y"を"T"に置換
df.query('Name.str.split("a").str[0] == "Y"') # "a"で分割
型を指定して取り出す(select_dtypes())
select_dtypes() で型を指定して列を取り出すことができます。
df.select_dtypes(include='int') # 型がint系の列 df.select_dtypes(include=['int', 'string']) # 型がint系またはstring系の列 df.select_dtypes(exclude='int') # 型がint系以外の列 df.select_dtypes(exclude=['int', 'string']) # 型がint系またはstring系以外の列
DataFrameに行・列を追加する
単数行を追加する(loc[])
1行を追加するには loc[] を使用できます。append() は廃止されました。
df.loc[len(df)] = {'Name': 'Kimura', 'Age': 28}
複数行を追加する(concat())
複数行追加するには pd.concat() を使用します。以前は append() もありましたが廃止されました。
rows = [ {'Name': 'Kimura', 'Age': 28}, {'Name': 'Nakano', 'Age': 62} ]
df = pd.concat([df, pd.DataFrame(rows)], ignore_index=True)
単数行を挿入する(分割+concat())
単数行を挿入する機能は提供されていません。無理矢理挿入する場合は分割して結合するしかなさそうです。
df2 = pd.DataFrame([{'Name': 'Kimura', 'Age': 28}])
df = pd.concat([df.iloc[:2], df2, df.iloc[2:]]).reset_index(drop=True)
単数列を追加する([...])
列を追加するには下記の様にします。全行に同じデータが入ります。
df['Gender'] = 'Unknown'
各行の値を指定するには下記の様にします。要素数が行数と一致している必要があります。
df['Gender'] = ['Male', 'Female', 'Male']
既存の列をベースに設定することもできます。
df['After_10_years'] = df['Age'] + 10
df['IsAdult'] = df['Age'] >= 20 # True/False
df['IsAdult'] = np.where(df['Age'] >= 20, 'Adult', 'Minor')
単数列を変更・追加する(assign())
assign() で列の値を変更したり、列を追加することができます。元の df は変更されません。
df = df.assign(Age=[37, 43, 55]) # Age列の値を変更 df = df.assign(Gender=['Male', 'Female', 'Male']) # Gender列を追加
単数列を挿入する(insert())
列数を指定して列を間に挿入することができます。下記の例は1列目の右側に 'Gender' 列を追加します。
df.insert(1, 'Gender', 'Unknown') df.insert(1, 'Gender', ['Male', 'Female', 'Male']) df.insert(1, 'Gender', df['Age'] + 10) df.insert(1, 'Gender', df['Age'] >= 20) df.insert(1, 'Gender', np.where(df['Age'] >= 20, 'Adult', 'Minor'))
複数列を追加する(concat())
concat() に axis=1 を指定して複数列を追加することができます。
df2 = pd.DataFrame({'Gender': ['Male', 'Female', 'Male'], 'IsAdult': [True, True, True]})
df = pd.concat([df, df2], axis=1)
列・行を削除する
列・行を削除する(drop())
drop() は列や行を削除します。
df = df.drop(index=0) # 行ラベル0の行を削除する df = df.drop(index=[0, 2]) # 行ラベル0と2の行を削除する df = df.drop(columns='Age') # 列ラベル'Age'の列を削除する df = df.drop(columns=['Name', 'Age']) # 列ラベル'Age'の列を削除する
列を取り出す(pop())
pop() は指定した列を取り出し、DataFrame から削除します。
df.pop('Age') # 戻り値はAge列。DataFrameからAge列が削除される
欠損値
欠損値(NaN, None, NA, NaT, ...)
pandas には型に応じていくつかの欠損値があります。ファイルから読み込む際には 空文字や NaN、nan、N/A、NA、null、NULL などの文字列も欠損値と見なされます(詳細)。int32 などの型は欠損値を扱うことができず、欠損値がある場合は float32 に変換されるので注意してください。Int32 であれば欠損値を扱えます。
np.nan : float系の欠損値。表示はNaN。 pd.NA : Int系, UInt系、boolean, string などの欠損値。表示は<NA>pd.NaT : datetime64[ns], timedelta64[ns] の欠損値。表示はNaT。 None : object の欠損値。表示はNone。
df = pd.DataFrame({
'Name': pd.Series([pd.NA], dtype='string'),
'Age': pd.Series([pd.NA], dtype='Int32'),
'Date': pd.Series([pd.NaT], dtype='datetime64[ns]'),
'Point': pd.Series([np.nan], dtype='float32'),
'Note': pd.Series([None], dtype='object'),
})
print(df)
# Name Age Date Point Note
# 0 <NA> <NA> NaT NaN None
欠損値か否かを判定する(isna())
isna() は値が欠損値か否かを判定します。互換性のために同等機能の isnull() も残されています。
pd.isna(df.loc[0, 'Name']) # True/False
欠損値を削除する(dropna())
dropna() は欠損値のある行を削除します。how='any' とするとひとつでも欠損値がある行、how='all' とするとすべてが欠損値の行を削除します。省略時は 'any' です。
df = pd.DataFrame([
['A1', 'B1', 'C1'],
['A2', 'B2', pd.NA],
['A3', pd.NA, pd.NA],
[pd.NA, pd.NA, pd.NA],
], columns=['A', 'B', 'C'], index=[1, 2, 3, 4])
print(df.dropna()) # how='any'と同義
print(df.dropna(how='any')) # ひとつでも欠損値があれば削除
print(df.dropna(how='all')) # すべて欠損値であれば削除
欠損値を固定値/平均値/中央値で埋める(fillna())
fillna() を用いて欠損値を埋めることができます。
df = pd.DataFrame({'A': [1.0, np.nan, np.nan, 4.0], 'B': [1.0, pd.NA, pd.NA, 4.0]})
df['A'] = df['A'].fillna(-1.0) # -1.0 で埋める
df['A'] = df['A'].fillna(df.mean()) # 平均値(2.5)で埋める
df['A'] = df['A'].fillna(df.median()) # 中央値(2.5)で埋める
df['A', 'B'] = df['A', 'B'].fillna(-1.0) # 複数の列に対して埋める
df = df.fillna(-1.0) # すべての列に対して埋める
欠損値を前出値/後出値で埋める(ffill(), bfill())
ffill(), bfill() を用いて欠損値を前出値、後出値で埋めることができます。
df['A'] = df['A'].ffill() # 前出の値(1.0)で埋める df['A'] = df['A'].bfill() # 後出の値(4.0)で埋める
欠損値を補完値で埋める(interpolate())
interpolate() を用いると欠損値を線形変化した場合の値や、スプライン曲線に従った場合の値で補完することができます。時系列に線形補完する場合は method='time' を指定します。その他の method 値については 詳細 を参照してください。
df = pd.DataFrame({'A': [1.0, np.nan, np.nan, 4.0], 'B': [1.0, pd.NA, pd.NA, 4.0]})
df['A'].interpolate() # method='lenear'と同義
df['A'].interpolate(method='linear') # 線形変化すると想定して補完
df['A'].interpolate(method='spline') # スプライン曲線に従って変化すると想定して補完
マルチインデックス
マルチインデックスのDataFrameを作成する(MultiIndex, set_index())
MultiIndex を用いて多階層のインデックスを持つ DataFrame を生成することができます。
index = pd.MultiIndex.from_tuples(
[(2025, 12), (2026, 1), (2026, 2)],
names=['Year', 'Month']
)
df = pd.DataFrame({'Sales': [100, 120, 140]}, index=index)
print(df)
# Sales
# Year Month
# 2025 12 100
# 1 120
# 2026 2 140
DataFrame 作成後に set_index() を使用して作成することもできます。
df = pd.DataFrame({
'Year': [2025, 2025, 2026],
'Month': [12, 1, 2],
'Sales': [100, 120, 140],
})
df = df.set_index(['Year', 'Month'])
print(df)
DataFrameをソートする
値でソートする(sort_values())
sort_values() は値で行や列をソートします。kind には quicksort(デフォルト), mergesort, heapsort, stable のいずれかを指定します。
df.sort_values('Age') # Age列の値で昇順にソートする
df.sort_values('Age', ascending=False) # 降順にソートする
df.sort_values('Age', inplace=True) # DataFrame自体を変更する
df.sort_values('Age', kind='quicksort') # ソートアルゴリズムを指定する
df.sort_values('Age', na_position='first') # 欠損値を先頭に配置する
df.sort_values('Age', ignore_index=True) # インデックスをリナンバリングする
df.sort_values(row, axis='columns') # 列方向にソートする
df.sort_values('Name', key=lamda s: s.str.len()) # ソート関数を指定する
ラベルでソートする(sort_index())
sort_index() は行ラベルや列ラベルで行や列をソートします。
df.sort_index() # 行ラベルで行を昇順にソートする df.sort_index(ascending=False) # 降順にソートする df.sort_index(na_position='first') # 欠損値を先頭に配置する df.sort_index(kind='quicksort') # ソートアルゴリズムを指定する df.sort_index(level=1) # マルチインデックスで行ラベルの1階層目(0始まり)でソートする df.sort_index(level=[0,1]) # マルチインデックスで行ラベルの0階層目を第1キー、1階層目を第2キーとしてソートする df.sort_index(sort_remaining=False) # level指定時他のインデックスではソートしない(デフォルトはソートする) df.sort_index(ignore_index=True) # インデックスをリナンバリングする df.sort_index(axis='columns') # 列ラベルで列をソートする df.sort_index(key=lamda s: s.str.len()) # ソート関数を指定する
DataFrameをマージする
DataFrameをマージする(merge())
merge() は二つの DataFrame をマージします。
df1 = pd.DataFrame({'Name': ['Yamada', 'Suzuki', 'Tanaka'], 'Age': [36, 42, 54]})
df2 = pd.DataFrame({'Name': ['Yamada', 'Suzuki', 'Tanaka'], 'Gender': ['Male', 'Female', 'Male']})
df3 = pd.merge(df1, df2)
# Name Age Gender
# 0 Yamada 36 Male
# 1 Suzuki 42 Female
# 2 Tanaka 54 Male
下記のようにも書けます。
df3 = df1.merge(df2)
結合キーを指定する(on, left_on, right_on)
通常はふたつの DataFrame で重複する列ラベルが結合キーとなりますが、on で明示的に指定することができます。
df3 = pd.merge(df1, df2, on='Name')
left_on, right_on を使用すると異なる列ラベルでも結合することができます。
df1 = pd.DataFrame({'Name': ['Yamada', 'Suzuki', 'Tanaka'], 'Age': [36, 42, 54]})
df2 = pd.DataFrame({'User': ['Yamada', 'Suzuki', 'Tanaka'], 'Gender': ['Male', 'Female', 'Male']})
df3 = pd.merge(df1, df2, left_on='Name', right_on='User')
# Name Age User Gender
# 0 Yamada 36 Yamada Male
# 1 Suzuki 42 Suzuki Female
# 2 Tanaka 54 Tanaka Male
結合方式(内部結合/外部結合/左結合/右結合/交差結合)を指定する(how)
how で結合方式を指定できます。デフォルトは inner で内部結合となり、左表・右表両方に存在する行が生成されます。
df1 = pd.DataFrame({'Name': ['Yamada', 'Suzuki', 'Tanaka'], 'Age': [36, 42, 54]})
df2 = pd.DataFrame({'Name': ['Yamada', 'Suzuki', 'Kimura'], 'Gender': ['Male', 'Female', 'Male']})
df3 = pd.merge(df1, df2, how='inner')
# Name Age Gender
# 0 Yamada 36 Male
# 1 Suzuki 42 Female
outer を指定すると外部結合となり、左表と右表どちらかに存在する行が生成されます。結合できない箇所は欠損値となります。
df1 = pd.DataFrame({'Name': ['Yamada', 'Suzuki', 'Tanaka'], 'Age': [36, 42, 54]})
df2 = pd.DataFrame({'Name': ['Yamada', 'Suzuki', 'Kimura'], 'Gender': ['Male', 'Female', 'Male']})
df3 = pd.merge(df1, df2, how='outer')
# Name Age Gender
# 0 Kimura NaN Male
# 1 Suzuki 42.0 Female
# 2 Tanaka 54.0 NaN
# 3 Yamada 36.0 Male
left を指定すると左結合となり、右表に存在しなくても、左表に存在する行が生成されます。
df1 = pd.DataFrame({'Name': ['Yamada', 'Suzuki', 'Tanaka'], 'Age': [36, 42, 54]})
df2 = pd.DataFrame({'Name': ['Yamada', 'Suzuki', 'Kimura'], 'Gender': ['Male', 'Female', 'Male']})
df3 = pd.merge(df1, df2, how='left')
# Name Age Gender
# 0 Yamada 36 Male
# 1 Suzuki 42 Female
# 2 Tanaka 54 NaN
right を指定すると右結合となり、左表に存在しなくても、右表に存在する行が生成されます。
df1 = pd.DataFrame({'Name': ['Yamada', 'Suzuki', 'Tanaka'], 'Age': [36, 42, 54]})
df2 = pd.DataFrame({'Name': ['Yamada', 'Suzuki', 'Kimura'], 'Gender': ['Male', 'Female', 'Male']})
df3 = pd.merge(df1, df2, how='right')
# Name Age Gender
# 0 Yamada 36.0 Male
# 1 Suzuki 42.0 Female
# 2 Kimura NaN Male
cross を指定すると交差結合となり、左表と右表のすべての組み合わせが生成されます。ラベルには _x, _y が追加されます。
df1 = pd.DataFrame({'Name': ['Yamada', 'Suzuki'], 'Age': [36, 42]})
df2 = pd.DataFrame({'Name': ['Tanaka', 'Kimura'], 'Age': [54, 28]})
df3 = pd.merge(df1, df2, how='cross')
Name_x Age_x Name_y Age_y
0 Yamada 36 Tanaka 54
1 Yamada 36 Kimura 28
2 Suzuki 42 Tanaka 54
3 Suzuki 42 Kimura 28
left_anti を指定すると左アンチ結合となり、左表にのみ存在する行みを生成します。right_anti も同様です。Pandas 3 で追加されました。
df3 = pd.mearge(df1, df2, how='left_anti') # 左アンチ結合 df3 = pd.mearge(df1, df2, how='right_anti') # 右アンチ結合
上記の outer や right で Age に欠損値が生じる場合、int64 型では欠損値を扱えないため、欠損値を扱える float64 に型変換されています。あらかじめ Int64 に変更しておくと整数型のまま欠損値を扱えます。
df1['Age'] = df1['Age'].astype('Int64')
列方向にマージする(join())
merge() は行方向のマージを行いますが、join() は行ラベルをキーとして列方向のマージを行います。
df1 = pd.DataFrame({'A': ['A0', 'A1', 'A2']})
df2 = pd.DataFrame({'B': ['B0', 'B1', 'B2']})
df3 = df1.join(df2)
# A B
# 0 A0 B0
# 1 A1 B1
# 2 A2 B2
merge() と違い pd.join() はサポートされていません。how のデフォルトは left となります。
DataFrameをグルーピングする
グルーピングする(groupby())
groupby() を用いて、指定した列の値で行をグルーピングし、グループ毎の平均値や中央値を計算することができます。
df = pd.DataFrame({
'Country': ['Japan', 'Japan', 'Japan', 'USA', 'USA', 'USA'],
'City': ['Tokyo', 'Tokyo', 'Osaka', 'NY', 'NY', 'LA'],
'Point': [72, 95, 63, 88, 92, 74],
})
# Country City Point
# 0 Japan Tokyo 72
# 1 Japan Tokyo 95
# 2 Japan Osaka 63
# 3 USA NY 88
# 4 USA NY 92
# 5 USA LA 74
df.groupby('Country').mean(numeric_only=True) # Countryでグルーピングして平均値を求める
# Point
# Country
# Japan 76.666667
# USA 84.666667
df.groupby(['Country', 'City']).mean(numeric_only=True) # CountryとCityでグルーピングして平均値を求める
# Point
# Country City
# Japan Osaka 63.0
# Tokyo 83.5
# USA LA 74.0
# NY 90.0
ラベルを変更する
行・列ラベルを変更する(columns, index, set_axis())
columns と index で列ラベル、行ラベルを変更することができます。set_axis() でも同様のことができます。
df.columns = ['NAMAE', 'NENREI'] # 列ラベルを変更 df.index = [1, 2, 3] # 行ラベルを変更 df.set_axis(['NAMAE', 'NENREI']) # 列ラベルを変更 df.set_axis([1, 2, 3], axis=='index') # 行ラベルを変更
行・列ラベルを変更する(rename())
rename() で行ラベル、列ラベルを一部のみ変更することができます。元の DataFrame は変更されません。
df = df.rename(columns={'Name': 'NAMAE', 'Age': 'NENREI'}, index={0:1, 1:2, 2:3})
ラムダ式で変更することもできます。
df = df.rename(index=lambda x: x + 1)
inplace=True を指定すると元の DataFrame が変更されます。
df.rename(columns={'Name': 'NAMAE', 'Age': 'NENREI'}, index={0:1, 1:2, 2:3}, inplace=True)
インデックスを設定する(set_index())
set_index() は現在のインデックス(行ラベル)を削除し、代わりに引数で指定した列を行ラベルとして使用します。
df = pd.DataFrame([
[10, 'Yamada', 36],
[20, 'Suzuki', 42],
[30, 'Tanaka', 54],
], columns=['Number', 'Name', 'Age'])
print(df)
# Number Name Age
# 0 10 Yamada 36
# 1 20 Suzuki 42
# 2 30 Tanaka 54
print(df.set_index('Number'))
# Name Age
# Number
# 10 Yamada 36
# 20 Suzuki 42
# 30 Tanaka 54
下記などのオプションを使用できます。
df.set_index(..., drop=False) # インデックスとして指定した列を列にも残す df.set_index(..., append=True) # 現在のインデックスに指定した列をインデックスとして追加する df.set_index(..., inplace=True) # DataFrame自体を変更する
インデックスをリセットする(reset_index())
reset_index() は現在の行ラベルを列に加え、新たに 0, 1, 2... のインデックス番号(行ラベル)を振りなおします。groupby() 実行後はグループキーが行ラベルとなるため、これを再度 0, 1, 2, ... のインデックス番号に振りなおす際などに使用されます。
df = pd.DataFrame([
['Yamada', 36],
['Suzuki', 42],
['Tanaka', 54],
], columns=['Name', 'Age'], index=[10, 20, 30])
print(df)
Name Age
10 Yamada 36
20 Suzuki 42
30 Tanaka 54
print(df.reset_index())
index Name Age
0 10 Yamada 36
1 20 Suzuki 42
2 30 Tanaka 54
下記などのオプションを使用できます。
df.reset_index(drop=True) # 元の行ラベルを破棄する df.reset_index(inplace=True) # 元のDataFrameを直接変更する df.reset_index(level=True) # マルチインデックスの一部のみを解除する df.reset_index(names='OldIndex') # 古いインデックスの列名を指定する
データに対して関数を実行する
Seriesの値に対して関数を実行する(map())
map() は各値に対して関数を実行します。
ser = pd.Series([98, 46, 82])
ser = ser.map(lambda x: x * 2) # 196, 92, 164
DataFrameの値対して関数を実行する(map())
DataFrame に対して map() を行うとすべての値に対して関数を実行します。列に対して行うとその列に対してのみ実行します。
df.map(lambda x: print(f"[{x}]")) # すべての値を[...]付で表示する
df['Age'] = df['Age'].map(lambda x: x + 1) # Age列の値に1加える
na_action='ignore' を指定すると欠損値に対しては処理を行いません。
df['Age'].map(lambda x: x + 1, na_action='ignore')
下記の様に関数に渡す名前付き変数を指定することもできます。
def add(x, n):
return x + n
df['Age'] = df['Age'].map(add, n=3)
列に対して関数を実行する(apply())
apply() は列に対して関数を実行します。関数は Series を引数として受け取れる必要があります。戻り値は各列に対して関数を実行した結果を格納した Series となります。
df = pd.DataFrame({
'X': [1, 2, 3],
'Y': [4, 5, 6],
'Z': [7, 8, 9]
})
ser = df.apply(sum)
# X 6
# Y 15
# Z 24
下記などの引数を指定できます。
df.apply(sum, axis='columns') # 列ではなく行に対して実行する df.apply(sum, raw=True) # SeriesではなくNumPy ndarrayとして渡す df.apply(sum, engine='numba') # Numba JITコンパイラを用いて高速化する df.apply(func, foo='Foo') # 関数に任意の名前付き引数を渡す
ループで回す
ループで回す(iterrows(), itertuples(), items(), to_numpy())
DataFrame は明示的なループ処理は行わず、ベクトル演算、apply()、query() などを使用するのが原則ですが、練習用やデバッグ用にループを回す場合は下記などの手段があります。
for index, row in df.iterrows(): # 遅い for col in df.columns: print(index, col, row[col]) for row in df.itertuples(): # iterrows()よりは早い print(row.Index, row.Name, row.Age) for col, rows in df.items(): # 列ごとに処理 for row in rows: print(col, row) for val in df.to_numpy(): # ループの中では比較的高速 print(val[0], val[1]) # for文を使用しない処理 df.apply(lambda row: print(row['Name'], row['Age']), axis=1)
集計や変更
値を置換する(replace())
replace() で値を置換することができます。下記はデータ中のすべての 'Yamada' を 'YAMADA' に置換します。
df = df.replace('Yamada', 'YAMADA')
複数指定することもできます。
df = df.replace({'Yamada': 'YAMADA', 'Suzuki': 'SUZUKI'})
df = df.replace(['Yamada', 'Suzuki'], ['YAMADA', 'SUZUKI'])
置換する対象列を限定することができます。下記の例では、Name 列のみを置換します。
df = df.replace({'Name': {'Yamada': 'YAMADA'})
正規表現を使用することもできます。
df = df.replace('^(yamada|Yamada)$', 'YAMADA', regex=True)
\1, \2, ... で正規表現の (...) にマッチした文字列を参照することができます。
df = pd.DataFrame({'Date': ['2026-02-15', '2026-02-16']})
df = df.replace('(.+)-(.+)-(.+)', r'\1年\2月\3日', regex=True)
集計処理をまとめて実行する(agg())
agg() は aggregate(集計)の意味で、各列に対する集計処理を一括で行います。下記の例では、A列、B列に対して最小値、最大値、合計値をまとめて計算しています。まとめて計算することで、個別に計算するよりも高速に計算することができます。
df = pd.DataFrame({
'A': [57, 83, 23],
'B': [36, 42, 54],
})
print(df.agg(["min", "max", "sum"]))
# A B
# min 23 36
# max 83 54
# sum 163 132
groupby() でグルーピングした各グループに対して、複数の集計処理を行うこともできます。
df = pd.DataFrame({
'Store': ['A', 'A', 'A', 'B', 'B'],
'Sales': [100, 200, 150, 300, 250],
'Quantity': [2, 3, 2, 5, 3],
})
print(df.groupby('Store').agg({
'Sales': ['min', 'max', 'mean', 'sum'],
'Quantity': 'sum'
})
Sales Quantity
min max mean sum sum
Store
A 100 200 150.0 450 7
B 250 300 275.0 550 8
下記の様に結果ラベルを指定することもできます。
print(df.groupby('Store').agg(
min_sales=('Sales', 'min'),
max_sales=('Sales', 'max'),
mean_sales=('Sales', 'mean'),
total_sales=('Sales', 'sum'),
total_count=('Quantity', 'sum')
)
# min_sales max_sales mean_sales total_sales total_count
# Store
# A 100 200 150.0 450 7
# B 250 300 275.0 550 5
値の出現回数をカウントする(value_counts())
value_counts() は Series や DataFrame の列に適用して、同じ値が出現した回数を集計します。下記の例では 1~6 の乱数を10,000個作成し、それぞれの値の出現回数を集計しています。デフォルトでは降順にソートされます。
ser = pd.Series(np.random.randint(1, 7, size=10000)) print(ser.value_counts()) # 2 1722 # 6 1717 # 3 1664 # 5 1644 # 4 1634 # 1 1619
下記などのオプションを指定できます。
ser.value_counts(normalize=True) # 出現回数の代わりに出現割合(0.0~1.0)を集計する ser.value_counts(dropna=False) # 欠損値も集計する ser.value_counts(ascending=True) # 昇順にソートする ser.value_counts(sort=False) # ソートしない ser.value_counts(bins=3) # 出現する数値を3等分し、それぞれのグループについて集計する
ピボット集計する(pivot_table())
pivot_table() は Excel のピボットテーブルのようにデータをクロス集計します。
df = pd.DataFrame({
'Store': ['A', 'A', 'A', 'B', 'B'],
'Item': ['X', 'Y', 'X', 'X', 'Y'],
'Sales': [100, 200, 150, 300, 250],
'Quantity': [2, 3, 2, 5, 3],
})
print(pd.pivot_table(
df,
values='Sales',
index='Store',
columns='Item',
aggfunc='sum'
))
# Item X Y
# Store
# A 250 200
# B 300 250
下記などのオプションを指定できます。
pd.pivot_table(..., fill_value=0) # # 欠損値を0とみなす pd.pivot_table(..., margins=True) # # 末尾に合計列・合計行(All)を追加する pd.pivot_table(..., margins_name='Total') # # 合計列・合計行のラベルを'All'から変更する pd.pivot_table(..., sort=False) # # 列ラベル・行ラベルでソートしない(デフォルトはソート)
値を上限・下限で制限する(clip())
clip(min, max) は DataFrame や Series の値の中から、min 以下の値を min に、max 以上の値を max に制限します。
df = df.clip(1, 100) # 下限を1、上限を100とする df = df.clip(lower=1) # 下限のみを指定する df = df.clip(upper=100) # 上限のみを指定する
下記の様に、列毎に異なる下限値・上限値を指定することもできます。
df = df.clip([10, 20, 30], [70, 80, 90])
下記のオプションを指定できます。
df.clip(..., axis='columns') # 列ではなく行に対して適用します df.clip(..., inplace=True) # DataFrame自体を変更します
条件により値を置換する(mask(), where())
mask() は条件にマッチした値を指定した値に置換します。
df = df.mask(df >= 40, 999) # 999に置換する df = df.mask(df >= 40) # NaNに置換する df = df.mask(df >= 40, df + 10) # +10した値に置換する df['A'] = df['A'].mask(df['A'] >= 40) # 列にだけ指定する
where() は条件にマッチしなかった値を指定した値に置換します。
df = df.where(df >= 40, 999) # 40未満の値を999に置換する
下記などのオプションを指定できます。
df.mask(..., inplace=True) # DataFrame自体を変更する df.mask(..., axis='columns') # 行に対して実行する
数値をランキングする(rank())
rank() は数値を小さい順に並べて1位, 2位, 3位...とランキングします。下記の例では、18が1位、22が2位、34が3位、43が4位、56が5位となります。3位が同順で2つ存在する場合はそれぞれが平均値の3.5位となります。
df = pd.DataFrame({'Score': [34, 22, 56, 18, 43]})
print(df.rank())
# Score
# 0 3.0
# 1 2.0
# 2 5.0
# 3 1.0
# 4 4.0
下記のオプションを指定できます。
df.rank(ascending=False) # 降順でランキングする(数値の大きな方が上位) df.rank(pct=True) # 0.0~1.0でランキングする。0.3以下のものを抽出すると上位30%のデータを取得できる df.rank(axis='columns') # 列ではなく行方向にランキングする df.rank(method='min') # 同順の場合の順位の計算方法を指定する(average,min,max,first,dense) df.rank(numeric_only=True) # ランキング対象を数値列のみに絞る df.rank(na_option='bottom') # NaNの順位を最下位とする(keep,top,bottom)
重複行を判定・削除する(duplicated(), drop_duplicates())
duplicated() は行を比較し、値がすべて前出のものと重複しているか否かを判定します。
df = pd.DataFrame([
['Yamada', 36],
['Suzuki', 42],
['Yamada', 36],
])
print(df.duplicated())
# 0 False ← 重複しているけど最初の行なのでFalse
# 1 False ← 重複していないのでFalse
# 2 True ← 重複していて最初の行ではないのでTrue
下記のオプションを指定できます。
df.duplicated(keep='first') # 重複行の中で最初の行はFalseとする(デフォルト) df.duplicated(keep='last') # 重複行の中で最後の行はFalseとする df.duplicated(keep=False) # 重複行をすべてTrueとする df.duplicated(subset=['A', 'B']) # 全列ではなく、A列とB列のみで判断する
drop_duplicates() は行を比較し、重複する行を削除します。
print(df.drop_duplicates()) # 0 1 # 0 Yamada 36 # 1 Suzuki 42
下記のオプションを指定できます。
df.drop_duplicates(keep='first') # 最初に出現する行を残す(デフォルト) df.drop_duplicates(keep='last') # 最後に出現する行を残す(デフォルト) df.drop_duplicates(keep=False) # 重複行をすべて削除する df.drop_duplicates(inplace=True) # DataFrame自体を書き換える df.drop_duplicates(ignore_index=True) # 削除後にインデックスを振りなおす
累積和・累積積・累積最大・累積最小を得る(cumsum(), cumprod(), cummax(), cummin())
cumsum()、cumprod()、cummax()、cummin() は累積和・累積積・累積最大・累積最小を算出します。
df = pd.DataFrame({
'A': [10, 20, 30, 40]
})
df['cumsum'] = df['A'].cumsum()
df['cumprod'] = df['A'].cumprod()
df['cummax'] = df['A'].cummax()
df['cummin'] = df['A'].cummin()
# A cumsum cumprod cummax cummin
# 0 10 10 10 10 10
# 1 20 30 200 20 10
# 2 30 60 6000 30 10
# 3 40 100 240000 40 10
下記のオプションを指定できます。
df.cumsum(axis='columns') # 列ではなく行方向に算出する df.cumsum(skipna=False) # NaN値を無視しない。NaN値以降はすべてNaN値とする df.cumsum(numeric_only=True) # 数値列のみを対象とする
その他
ワイド形式をロング形式に変換する(melt())
melt() は横方向のワイド形式の DataFrame を縦方向のロング形式に変換します。
df = pd.DataFrame({
"name": ["Yamada", "Suzuki"],
"A": [10, 20],
"B": [30, 40],
"C": [50, 60],
"D": [70, 80],
})
print(df)
# name A B C D
# 0 Yamada 10 30 50 70
# 1 Suzuki 20 40 60 80
print(df.melt(id_vars="name"))
# name variable value
# 0 Yamada A 10
# 1 Suzuki A 20
# 2 Yamada B 30
# 3 Suzuki B 40
# 4 Yamada C 50
# 5 Suzuki C 60
# 6 Yamada D 70
# 7 Suzuki D 80
行と列を転置する(T)
T は行と列を入れ替えます。
df = pd.DataFrame({
'Name': ['Yamada', 'Suzuki', 'Tanaka'],
'Age': [36, 42, 54]
})
print(df)
# Name Age
# 0 Yamada 36
# 1 Suzuki 42
# 2 Tanaka 54
print(df.T)
# 0 1 2
# Name Yamada Suzuki Tanaka
# Age 36 42 54