Pandas#
# 警告メッセージを非表示
import warnings
warnings.filterwarnings("ignore")
PandasはNumPyのarrayのようにデータを扱うパッケージだが,Pandas特有のデータ構造を提供し複雑なデータを扱いやすくしている。例えば,行列にはラベルを使うことにより,インデックス番号だけではなくラベル名(例えば,GDP)を使って操作することが可能となる。PandasにはDataFrame(データフレーム)とSeries(シリーズ)と呼ばれるオブジェクトがある。前者はエクセルのスプレッド・シートをイメージすれば良いだろう。後者は,スプレッド・シートから1つの行または列を取り出したようなデータと思えば良い。また,PandasはNumPyに基づいているため,ベクトル演算(ブロードキャスティング)の機能が使える。
ここで説明できない他の使い方についてはこのサイトとこのサイトが参考になる。
通常pdという名前で読み込む。
import pandas as pd
データの読み込みとデータのチェック#
様々なデータを読み込むことが可能だが,ここではread_csv()関数を使ってインターネット上の.csvファイルを読み込む。
# url の設定
url = 'https://raw.githubusercontent.com/Haruyama-KobeU/Py4Basics/master/data/data1.csv'
# 読み込み
df = pd.read_csv(url)
df全体を表示させる。
df
| year | gdp | inv | con | pop | id | |
|---|---|---|---|---|---|---|
| 0 | 2000 | 100 | 20.0 | 80.0 | 8 | a |
| 1 | 2001 | 95 | 25.0 | 70.0 | 9 | b |
| 2 | 2002 | 93 | 21.0 | 72.0 | 10 | a |
| 3 | 2003 | 100 | 30.0 | 70.0 | 11 | b |
| 4 | 2004 | 110 | 39.0 | 71.0 | 12 | a |
| 5 | 2005 | 115 | 55.0 | 60.0 | 14 | b |
| 6 | 2006 | 113 | 50.0 | 63.0 | 15 | a |
| 7 | 2007 | 118 | 53.0 | 65.0 | 17 | b |
| 8 | 2008 | 119 | 60.0 | 59.0 | 18 | a |
| 9 | 2009 | 200 | 62.0 | NaN | 20 | b |
| 10 | 2010 | 210 | NaN | NaN | 21 | a |
行ラベルがインデックス(番号)のままなので,列yearを行ラベルに設定する。
set_index():選択された列を行ラベルにするメソッド
df = df.set_index('year')
df
| gdp | inv | con | pop | id | |
|---|---|---|---|---|---|
| year | |||||
| 2000 | 100 | 20.0 | 80.0 | 8 | a |
| 2001 | 95 | 25.0 | 70.0 | 9 | b |
| 2002 | 93 | 21.0 | 72.0 | 10 | a |
| 2003 | 100 | 30.0 | 70.0 | 11 | b |
| 2004 | 110 | 39.0 | 71.0 | 12 | a |
| 2005 | 115 | 55.0 | 60.0 | 14 | b |
| 2006 | 113 | 50.0 | 63.0 | 15 | a |
| 2007 | 118 | 53.0 | 65.0 | 17 | b |
| 2008 | 119 | 60.0 | 59.0 | 18 | a |
| 2009 | 200 | 62.0 | NaN | 20 | b |
| 2010 | 210 | NaN | NaN | 21 | a |
Tip
df.set_index('year')は直接dfに影響を与えない。単に,書き換えるとどうなるかを表示している。ここではdfに再度割り当てることによりdf自体を上書きしている。出力にある
NaN(Not a Number)は欠損値を示す。行ラベルに
yearという列名が残るが,それを消す方法:メソッド
.rename_axis('')を使う。ここで''は空の文字列である。.rename_axis(None)でも同じ結果となる。df.index.name = ''とする。ここで''は空の文字列
行数が大きい場合(例えば,10000),全てを表示してもあまり意味がない。そこでよく使うメソッドに最初や最後の数行だけを表示すものがある。
dfの最初の5行を表示させる。
df.head()
| gdp | inv | con | pop | id | |
|---|---|---|---|---|---|
| year | |||||
| 2000 | 100 | 20.0 | 80.0 | 8 | a |
| 2001 | 95 | 25.0 | 70.0 | 9 | b |
| 2002 | 93 | 21.0 | 72.0 | 10 | a |
| 2003 | 100 | 30.0 | 70.0 | 11 | b |
| 2004 | 110 | 39.0 | 71.0 | 12 | a |
引数に2を指定すると最初の2行のみ表示される。
df.head(2)
| gdp | inv | con | pop | id | |
|---|---|---|---|---|---|
| year | |||||
| 2000 | 100 | 20.0 | 80.0 | 8 | a |
| 2001 | 95 | 25.0 | 70.0 | 9 | b |
最後の5行を表示させる。引数に整数を入れて表示行数を指定することも可能。
df.tail()
| gdp | inv | con | pop | id | |
|---|---|---|---|---|---|
| year | |||||
| 2006 | 113 | 50.0 | 63.0 | 15 | a |
| 2007 | 118 | 53.0 | 65.0 | 17 | b |
| 2008 | 119 | 60.0 | 59.0 | 18 | a |
| 2009 | 200 | 62.0 | NaN | 20 | b |
| 2010 | 210 | NaN | NaN | 21 | a |
dfの情報を確認する。
df.info()
<class 'pandas.core.frame.DataFrame'>
Index: 11 entries, 2000 to 2010
Data columns (total 5 columns):
# Column Non-Null Count Dtype
--- ------ -------------- -----
0 gdp 11 non-null int64
1 inv 10 non-null float64
2 con 9 non-null float64
3 pop 11 non-null int64
4 id 11 non-null object
dtypes: float64(2), int64(2), object(1)
memory usage: 528.0+ bytes
説明:
<class 'pandas.core.frame.DataFrame'>クラス名
type(1)とするとintというデータ型が表示するが,これはクラス名でもある。print(type(1))とすると<class 'int'>と表示される。
Int64Index: 11 entries, 2000 to 2010行のインデックスの情報
データ型は
Int64(整数)(データ型には64や32という数字がついている場合がある。それらは数字をコンピュータのメモリに記憶させる際,何ビット必要かを示している。より重要なのはInt(整数)の部分である。)11個のデータで2000から2010
Data columns (total 5 columns):データ列の数(5つ)
gdp 11 non-null int64データ型は
int6411のデータがあり,欠損値なし(
non-nullとは欠損値ではないデータ)
inv 10 non-null float64データ型は
float6410のデータがあり,欠損値数は1(=11-10)
con 9 non-null float64データ型は
float649のデータがあり,欠損値数は2(=11-9)
pop 11 non-null int64データ型は
int6411のデータがあり,欠損値数なし
id 11 non-null objectデータ型は
object(文字列などの場合)11のデータがあり,欠損値数なし
dtypes: float64(2), int64(2), object(1)dfの列にどのようなのデータ型かを示すfloat64とint64が2列つずつ,文字列は1列
memory usage: 528.0+ bytesメモリー使用量は約528.0バイト
データを読み込んだら必ずinfo()を使って欠損値の数や列のデータ型を確認すること。
また,データの統計的な特徴は次のメソッドでチェックできる。
df.describe()
| gdp | inv | con | pop | |
|---|---|---|---|---|
| count | 11.000000 | 10.000000 | 9.000000 | 11.000000 |
| mean | 124.818182 | 41.500000 | 67.777778 | 14.090909 |
| std | 40.715644 | 16.473885 | 6.666667 | 4.482288 |
| min | 93.000000 | 20.000000 | 59.000000 | 8.000000 |
| 25% | 100.000000 | 26.250000 | 63.000000 | 10.500000 |
| 50% | 113.000000 | 44.500000 | 70.000000 | 14.000000 |
| 75% | 118.500000 | 54.500000 | 71.000000 | 17.500000 |
| max | 210.000000 | 62.000000 | 80.000000 | 21.000000 |
count:観測値の数mean:平均std:標準偏差min:最小値max:最大値25%:第1四分位数50%:第2四分位数(中央値)75%:第3四分位数max:最大値
次のデータ属性を使ってdfの行と列の長さを確認することができる。返値はタプルで,(行の数,列の数)と解釈する。
df.shape
(11, 5)
返値はタプルなので,行数は以下で取得できる。
df.shape[0]
11
以下でも行数を示すことができる。
len(df)
11
DataFrameの構成要素#
DataFrameには様々な属性があるが,ここでは以下の3点について説明する。
データ(
df.to_numpy())列ラベル(
df.columns)行ラベル(
df.index)
まずデータ自体を抽出する。
df.to_numpy()
array([[100, 20.0, 80.0, 8, 'a'],
[95, 25.0, 70.0, 9, 'b'],
[93, 21.0, 72.0, 10, 'a'],
[100, 30.0, 70.0, 11, 'b'],
[110, 39.0, 71.0, 12, 'a'],
[115, 55.0, 60.0, 14, 'b'],
[113, 50.0, 63.0, 15, 'a'],
[118, 53.0, 65.0, 17, 'b'],
[119, 60.0, 59.0, 18, 'a'],
[200, 62.0, nan, 20, 'b'],
[210, nan, nan, 21, 'a']], dtype=object)
type(df.to_numpy())
numpy.ndarray
これで分かることは,メインのデータの部分はNumPyのndarray(n次元array)であることが分かる。即ち,PandasはNumPyに基づいて構築されており,データ値の計算などはarrayが裏で動いているということである。また行と列のラベルを追加し,より直感的に使えるように拡張しているのである。
次に列ラベルを取り出してみる。
df.columns
Index(['gdp', 'inv', 'con', 'pop', 'id'], dtype='object')
dtype='object'から列ラベルに使われているデータ型(dtype)はオブジェクト型(object)だとわかる。
オブジェクト型とは文字型を含む「その他」のデータ型と理解すれば良いだろう。
dtype='object'とdtype=objectは同じ意味。
列ラベル自体のクラスは次のコードで調べることができる。
type(df.columns)
pandas.core.indexes.base.Index
dir()もしくはpy4macroモジュールに含まれるsee()関数で調べると多くのメソッドや属性が確認できるが,その中に.tolist()が含まれており,これを使うことにより列ラベルをリストに変換することができる。
df_columns = df.columns.tolist()
df_columns
['gdp', 'inv', 'con', 'pop', 'id']
行ラベルについても同じことができる。
df.index
Index([2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010], dtype='int64', name='year')
行ラベルのデータ型dtypeは整数であるint64。列yearを行ラベルに指定したため,name='year'はその列ラベルを表示している。行ラベルのデータ型(クラス)は
type(df.index)
pandas.core.indexes.base.Index
であり,ラベルをリストとして抽出することもできる。
df_index = df.index.tolist()
df_index
[2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010]
要素の抽出#
NumPyのarrayの場合,[,]を使い要素を抽出した。Pandasの場合,様々な抽出方法があるが,覚えやすく少しでも間違いの可能性を減らすために,そして可読性向上のためにarrayに対応する以下の2つの方法を使うことにする。
ラベルを使う方法:
.loc[,]インデックスを使う方法:
.iloc[,](これはarrayの[ ]と同じと考えて良い)
1つ目のlocはラベルのlocationと覚えよう。2つ目はのilocのiはインデックス(index)のiであり,index locationという意味である。使い方はarrayの場合と基本的に同じである。
,の左は行,右は列を表す。行または列を連続して選択する(slicing)場合は
:を使う。(start:end):の左右を省略する場合は,「全て」という意味になる。:の左を省略すると「最初から」という意味になる。:の右を省略すると「最後まで」という意味になる。.loc[,]の場合,endを含む。(要注意!).iloc[,]の場合,endは含まず,その1つ前のインデックスまでが含まれる。
,の右に書く:は省略可能であるが省略しないことを推奨する。
「特例」として.loc[,]と.iloc[,]以外に
ラベルと
[]だけを使い列を選択する方法
も説明する。
Warning
.loc[,]の場合,endを含む。(要注意!).iloc[,]の場合,endは含まず,その1つ前のインデックスまでが含まれる。
.loc[,](ラベル使用)#
1つの行をSeriesとして抽出
df.loc[2005,:]
gdp 115
inv 55.0
con 60.0
pop 14
id b
Name: 2005, dtype: object
1つの行をDataFrameとして抽出
df.loc[[2005],:]
| gdp | inv | con | pop | id | |
|---|---|---|---|---|---|
| year | |||||
| 2005 | 115 | 55.0 | 60.0 | 14 | b |
複数行を抽出
df.loc[[2005, 2010],:]
| gdp | inv | con | pop | id | |
|---|---|---|---|---|---|
| year | |||||
| 2005 | 115 | 55.0 | 60.0 | 14 | b |
| 2010 | 210 | NaN | NaN | 21 | a |
複数行を連続抽出(slicing)
df.loc[2005:2008,:]
| gdp | inv | con | pop | id | |
|---|---|---|---|---|---|
| year | |||||
| 2005 | 115 | 55.0 | 60.0 | 14 | b |
| 2006 | 113 | 50.0 | 63.0 | 15 | a |
| 2007 | 118 | 53.0 | 65.0 | 17 | b |
| 2008 | 119 | 60.0 | 59.0 | 18 | a |
1つの列をSeriesとして抽出
df.loc[:,'gdp']
year
2000 100
2001 95
2002 93
2003 100
2004 110
2005 115
2006 113
2007 118
2008 119
2009 200
2010 210
Name: gdp, dtype: int64
複数列を抽出
df.loc[:,['gdp','pop']]
| gdp | pop | |
|---|---|---|
| year | ||
| 2000 | 100 | 8 |
| 2001 | 95 | 9 |
| 2002 | 93 | 10 |
| 2003 | 100 | 11 |
| 2004 | 110 | 12 |
| 2005 | 115 | 14 |
| 2006 | 113 | 15 |
| 2007 | 118 | 17 |
| 2008 | 119 | 18 |
| 2009 | 200 | 20 |
| 2010 | 210 | 21 |
複数列を連続抽出(slicing)
df.loc[:,'inv':'pop']
| inv | con | pop | |
|---|---|---|---|
| year | |||
| 2000 | 20.0 | 80.0 | 8 |
| 2001 | 25.0 | 70.0 | 9 |
| 2002 | 21.0 | 72.0 | 10 |
| 2003 | 30.0 | 70.0 | 11 |
| 2004 | 39.0 | 71.0 | 12 |
| 2005 | 55.0 | 60.0 | 14 |
| 2006 | 50.0 | 63.0 | 15 |
| 2007 | 53.0 | 65.0 | 17 |
| 2008 | 60.0 | 59.0 | 18 |
| 2009 | 62.0 | NaN | 20 |
| 2010 | NaN | NaN | 21 |
.iloc[](インデックス使用)#
1つの行をSeriesとして抽出
df.iloc[1,:]
gdp 95
inv 25.0
con 70.0
pop 9
id b
Name: 2001, dtype: object
複数行を抽出
df.iloc[[1,4],:]
| gdp | inv | con | pop | id | |
|---|---|---|---|---|---|
| year | |||||
| 2001 | 95 | 25.0 | 70.0 | 9 | b |
| 2004 | 110 | 39.0 | 71.0 | 12 | a |
複数行を連続抽出(slicing)
df.iloc[1:4,:]
| gdp | inv | con | pop | id | |
|---|---|---|---|---|---|
| year | |||||
| 2001 | 95 | 25.0 | 70.0 | 9 | b |
| 2002 | 93 | 21.0 | 72.0 | 10 | a |
| 2003 | 100 | 30.0 | 70.0 | 11 | b |
1つの列をSeriesとして抽出
df.iloc[:,1]
year
2000 20.0
2001 25.0
2002 21.0
2003 30.0
2004 39.0
2005 55.0
2006 50.0
2007 53.0
2008 60.0
2009 62.0
2010 NaN
Name: inv, dtype: float64
1つの列をDataFrameとして抽出
df.iloc[:,[1]]
| inv | |
|---|---|
| year | |
| 2000 | 20.0 |
| 2001 | 25.0 |
| 2002 | 21.0 |
| 2003 | 30.0 |
| 2004 | 39.0 |
| 2005 | 55.0 |
| 2006 | 50.0 |
| 2007 | 53.0 |
| 2008 | 60.0 |
| 2009 | 62.0 |
| 2010 | NaN |
複数列を選択
df.iloc[:,[1,3]]
| inv | pop | |
|---|---|---|
| year | ||
| 2000 | 20.0 | 8 |
| 2001 | 25.0 | 9 |
| 2002 | 21.0 | 10 |
| 2003 | 30.0 | 11 |
| 2004 | 39.0 | 12 |
| 2005 | 55.0 | 14 |
| 2006 | 50.0 | 15 |
| 2007 | 53.0 | 17 |
| 2008 | 60.0 | 18 |
| 2009 | 62.0 | 20 |
| 2010 | NaN | 21 |
複数列を連続抽出(slicing)
df.iloc[:,1:3]
| inv | con | |
|---|---|---|
| year | ||
| 2000 | 20.0 | 80.0 |
| 2001 | 25.0 | 70.0 |
| 2002 | 21.0 | 72.0 |
| 2003 | 30.0 | 70.0 |
| 2004 | 39.0 | 71.0 |
| 2005 | 55.0 | 60.0 |
| 2006 | 50.0 | 63.0 |
| 2007 | 53.0 | 65.0 |
| 2008 | 60.0 | 59.0 |
| 2009 | 62.0 | NaN |
| 2010 | NaN | NaN |
[]で列の選択(ラベル使用)#
1つの列をSeriesとして抽出
df['gdp']
year
2000 100
2001 95
2002 93
2003 100
2004 110
2005 115
2006 113
2007 118
2008 119
2009 200
2010 210
Name: gdp, dtype: int64
1つの列をDataFrameとして抽出
df[['gdp']]
| gdp | |
|---|---|
| year | |
| 2000 | 100 |
| 2001 | 95 |
| 2002 | 93 |
| 2003 | 100 |
| 2004 | 110 |
| 2005 | 115 |
| 2006 | 113 |
| 2007 | 118 |
| 2008 | 119 |
| 2009 | 200 |
| 2010 | 210 |
複数列を選択
df[['gdp','pop']]
| gdp | pop | |
|---|---|---|
| year | ||
| 2000 | 100 | 8 |
| 2001 | 95 | 9 |
| 2002 | 93 | 10 |
| 2003 | 100 | 11 |
| 2004 | 110 | 12 |
| 2005 | 115 | 14 |
| 2006 | 113 | 15 |
| 2007 | 118 | 17 |
| 2008 | 119 | 18 |
| 2009 | 200 | 20 |
| 2010 | 210 | 21 |
ある条件の下で行の抽出#
1つの条件の場合#
例1:GDPが100未満の行の抽出#
まず条件を作る。
df['gdp'] < 100
year
2000 False
2001 True
2002 True
2003 False
2004 False
2005 False
2006 False
2007 False
2008 False
2009 False
2010 False
Name: gdp, dtype: bool
この条件では,GDPが100未満の行はTrue,以上の行はFalseとなる。この条件をcondというの変数に割り当てる。()を省いても良いが,ある方が分かりやすいだろう。
cond = ( df['gdp'] < 100 )
condを.loc[,]の引数とすることにより,Trueの行だけを抽出できる。(注意:condを使って行を抽出しようとしているので,の左側に書く。)
df.loc[cond,:]
| gdp | inv | con | pop | id | |
|---|---|---|---|---|---|
| year | |||||
| 2001 | 95 | 25.0 | 70.0 | 9 | b |
| 2002 | 93 | 21.0 | 72.0 | 10 | a |
この条件の下で\(inv\)だけを抽出したい場合
df.loc[cond,'inv']
とする。
Warning
以下のように抽出を連続ですることも可能だが,避けるように!
df.loc[cond,:]['inv']df.loc[cond,:].loc[:,'inv']
例2:idがaの行を抽出#
cond = ( df.loc[:,'id'] == 'a' )
df.loc[cond,:]
| gdp | inv | con | pop | id | |
|---|---|---|---|---|---|
| year | |||||
| 2000 | 100 | 20.0 | 80.0 | 8 | a |
| 2002 | 93 | 21.0 | 72.0 | 10 | a |
| 2004 | 110 | 39.0 | 71.0 | 12 | a |
| 2006 | 113 | 50.0 | 63.0 | 15 | a |
| 2008 | 119 | 60.0 | 59.0 | 18 | a |
| 2010 | 210 | NaN | NaN | 21 | a |
複数条件の場合#
例3#
以下の条件の両方が満たされる場合:
gdpが100以上invが30以下
それぞれの条件を作成する。
cond1 = ( df['gdp'] >= 100 )
cond2 = ( df['inv'] <= 30 )
2つの条件が同時に満たされる条件を作成する。
cond = ( cond1 & cond2 )
condを引数に使い行を抽出する。
df.loc[cond, :]
| gdp | inv | con | pop | id | |
|---|---|---|---|---|---|
| year | |||||
| 2000 | 100 | 20.0 | 80.0 | 8 | a |
| 2003 | 100 | 30.0 | 70.0 | 11 | b |
例4#
以下の条件のどちらかが満たされる場合:
gdpは200以上conは60以下
cond1 = ( df['gdp'] >= 200 )
cond2 = ( df['con'] <= 60 )
cond = ( cond1 | cond2 )
df.loc[cond, :]
| gdp | inv | con | pop | id | |
|---|---|---|---|---|---|
| year | |||||
| 2005 | 115 | 55.0 | 60.0 | 14 | b |
| 2008 | 119 | 60.0 | 59.0 | 18 | a |
| 2009 | 200 | 62.0 | NaN | 20 | b |
| 2010 | 210 | NaN | NaN | 21 | a |
例5#
以下の条件のどちらかが満たされ
gdpは200以上conは60以下
かつ以下の条件も同時に満たされる場合:
idがaと等しい
cond1 = ( df['gdp'] >= 200 )
cond2 = ( df['con'] <= 60 )
cond3 = ( df['id'] == 'a' )
cond = ( (cond1 | cond2) & cond3 )
df.loc[cond, :]
| gdp | inv | con | pop | id | |
|---|---|---|---|---|---|
| year | |||||
| 2008 | 119 | 60.0 | 59.0 | 18 | a |
| 2010 | 210 | NaN | NaN | 21 | a |
query()#
query()というメソッドでは文字列を使い行の抽出コードを書くことができる。これにより直感的なコード書くことが可能である。
例1の場合:#
df.query('gdp < 100')
| gdp | inv | con | pop | id | |
|---|---|---|---|---|---|
| year | |||||
| 2001 | 95 | 25.0 | 70.0 | 9 | b |
| 2002 | 93 | 21.0 | 72.0 | 10 | a |
例2の場合#
df.query('id == "a"')
| gdp | inv | con | pop | id | |
|---|---|---|---|---|---|
| year | |||||
| 2000 | 100 | 20.0 | 80.0 | 8 | a |
| 2002 | 93 | 21.0 | 72.0 | 10 | a |
| 2004 | 110 | 39.0 | 71.0 | 12 | a |
| 2006 | 113 | 50.0 | 63.0 | 15 | a |
| 2008 | 119 | 60.0 | 59.0 | 18 | a |
| 2010 | 210 | NaN | NaN | 21 | a |
例3の場合#
df.query('(gdp >= 100) & (inv <= 30)')
| gdp | inv | con | pop | id | |
|---|---|---|---|---|---|
| year | |||||
| 2000 | 100 | 20.0 | 80.0 | 8 | a |
| 2003 | 100 | 30.0 | 70.0 | 11 | b |
例4の場合#
df.query('(gdp >= 200) | (con <= 60)')
| gdp | inv | con | pop | id | |
|---|---|---|---|---|---|
| year | |||||
| 2005 | 115 | 55.0 | 60.0 | 14 | b |
| 2008 | 119 | 60.0 | 59.0 | 18 | a |
| 2009 | 200 | 62.0 | NaN | 20 | b |
| 2010 | 210 | NaN | NaN | 21 | a |
例5の場合#
df.query('(gdp >= 200 | con <= 60) & (id == "a")')
| gdp | inv | con | pop | id | |
|---|---|---|---|---|---|
| year | |||||
| 2008 | 119 | 60.0 | 59.0 | 18 | a |
| 2010 | 210 | NaN | NaN | 21 | a |
Tip
変数で条件を設定する場合@が必要になる。例えば,変数zという変数があるとしよう。
z = 100
変数zの値に基づいて行の抽出をする場合は次のようにする。
df.query('gdp < @z')
gdp
inv
con
pop
id
year
2001
95
25.0
70.0
9
b
2002
93
21.0
72.0
10
a
列と行の追加と削除#
列の追加 [ ]#
[]に列ラベルを使って列を抽出することができるが,[]は列の追加にも使えるので,ここではその使い方を説明する。まず,全ての行が1.0となる列を作成するとしよう。その場合,以下のようにする。
df['Intercept'] = 1.0
df.head(2)
| gdp | inv | con | pop | id | Intercept | |
|---|---|---|---|---|---|---|
| year | ||||||
| 2000 | 100 | 20.0 | 80.0 | 8 | a | 1.0 |
| 2001 | 95 | 25.0 | 70.0 | 9 | b | 1.0 |
次の例では既存の列から新たな列を作成する。まず1人当たりGDPの計算を計算し,それを変数gdp_pcに割り当てる。
gdp_pc = df['gdp']/df['pop']
gdp_pc.head()
year
2000 12.500000
2001 10.555556
2002 9.300000
2003 9.090909
2004 9.166667
dtype: float64
これはSeriesであり,GDPpcとしてdfに追加する。
df['gdp_pc'] = gdp_pc
df.head(2)
| gdp | inv | con | pop | id | Intercept | gdp_pc | |
|---|---|---|---|---|---|---|---|
| year | |||||||
| 2000 | 100 | 20.0 | 80.0 | 8 | a | 1.0 | 12.500000 |
| 2001 | 95 | 25.0 | 70.0 | 9 | b | 1.0 | 10.555556 |
列の追加 .loc[,]#
.loc[]は行と列の抽出に使ったが,追加にも使える。[]と同じと考えれば良い。次の例ではpopを2倍した列を追加している。
df.loc[:,'2pop'] = 2*df['pop']
列の削除 [ ]#
del df['2pop']
列の削除 drop()#
DataFrameには.drop()というメソッドが用意されているので,それを使うことも可能である。
下のコードの説明:
オプション
axis=の値をcolumnsの代わりに1でも可コピーを作るだけなので,元のdfを書き換えたい場合は以下のどちらかが必要
dfに代入するオプション
inplace=True(デフォルトはFalse)を追加する。
df = df.drop(['Intercept','gdp_pc'], axis='columns')
# df.drop('Intercept', axis='columns', inplace=True)
行の追加 .loc[,]#
行と列の抽出,そして列の追加に使ったが,行の追加にも使える。
df.loc[2011,:] = [215, 100, 115, 22, 'b']
df.tail(3)
| gdp | inv | con | pop | id | |
|---|---|---|---|---|---|
| year | |||||
| 2009 | 200.0 | 62.0 | NaN | 20.0 | b |
| 2010 | 210.0 | NaN | NaN | 21.0 | a |
| 2011 | 215.0 | 100.0 | 115.0 | 22.0 | b |
上の例では,最初の4つの要素は整数として入力されたが,dfの中では浮動小数点に変換されている。
行の削除 drop()#
これは列を削除する際に紹介したメソッド.drop()である。
オプション
axis=の値をrowsの代わりに0でも可コピーを作るだけなので,元のdfを書き換えたい場合は以下のどちらかが必要
dfに代入するオプション
inplace=True(デフォルトはFalse)を追加する。
df = df.drop(2011, axis='rows')
# df.drop(2011, axis=0, inplace=True)
欠損値の扱い#
Pandasでは欠損値はNaNと表示されるが,naもしくはnullと呼んだりもする。
欠損値の確認#
欠損値があるかどうかの確認は,df.info()でもできるが,以下のメソッドを組み合わせることでも可能である。
isna():それぞれの要素についてNaNの場合Trueを,そうでない場合はFalseを返す。(DataFrameの全ての要素がTrue/Falseとなる。)sum(axis='rows'):dfの上から下に行(rows)を縦断して,それぞれの列の中にあるTrue数える。rowsは複数!(0でも可)
sum(axis='columns'):dfの左から右に列(columns)を横断して,それぞれの行の中にあるTrueを数える。columnsは複数!(1でも可)
(注意)sum()のaxisは「行を縦断」か「列を横断」かを指定する。
df.isna().sum(axis='rows')
gdp 0
inv 1
con 2
pop 0
id 0
dtype: int64
invとconにNaNがあることがわかる。axis='columns'を設定するとNaNがある行を確認できる。
df.isna().sum(axis='columns')
year
2000 0
2001 0
2002 0
2003 0
2004 0
2005 0
2006 0
2007 0
2008 0
2009 1
2010 2
dtype: int64
NaNがある行だけを抽出したい場合がある。その場合はメソッドany()が役に立つ。
any(axis='rows'):dfの上から下に行(rows)を縦断して,それぞれの列の中で一つ以上Trueがある場合にはTrueを,一つもない場合はFalseを返す。rowsは複数!(0でも可)
any(axis='columns'):dfの左から右に列(columns)を横断して,それぞれの行の中で一つ以上Trueがある場合にはTrueを,一つもない場合はFalseを返す。columnsは複数!(1でも可)
(注意)any()のaxisは「行を縦断」か「列を横断」かを指定する。
cond = df.isna().any(axis='columns')
df.loc[cond,:]
| gdp | inv | con | pop | id | |
|---|---|---|---|---|---|
| year | |||||
| 2009 | 200.0 | 62.0 | NaN | 20.0 | b |
| 2010 | 210.0 | NaN | NaN | 21.0 | a |
これでNaNがある行を抽出することができる。
欠損値がある行の削除#
欠損値がある行を削除するには,dfのメソッド.dropna()を使う。次のコードでは,欠損値がある全ての行を削除する。
df.dropna()
| gdp | inv | con | pop | id | |
|---|---|---|---|---|---|
| year | |||||
| 2000 | 100.0 | 20.0 | 80.0 | 8.0 | a |
| 2001 | 95.0 | 25.0 | 70.0 | 9.0 | b |
| 2002 | 93.0 | 21.0 | 72.0 | 10.0 | a |
| 2003 | 100.0 | 30.0 | 70.0 | 11.0 | b |
| 2004 | 110.0 | 39.0 | 71.0 | 12.0 | a |
| 2005 | 115.0 | 55.0 | 60.0 | 14.0 | b |
| 2006 | 113.0 | 50.0 | 63.0 | 15.0 | a |
| 2007 | 118.0 | 53.0 | 65.0 | 17.0 | b |
| 2008 | 119.0 | 60.0 | 59.0 | 18.0 | a |
このメソッドは,欠損値を削除するとどうなるかを示すだけでありdf自体は影響は受けない。df自体からNaNがある行を削除する場合はinplace=Trueのオプション(デフォルトではFalseになっている)を加えて
df.dropna(inplace=True)
とするか,削除後のdfを変数dfに再度割り当てる。
df = df.dropna()
一方で,ある列にNaNがある場合のみ行を削除したい場合もあるだろう。その場合は引数subsetを使う。
df.dropna(subset=['inv'])
| gdp | inv | con | pop | id | |
|---|---|---|---|---|---|
| year | |||||
| 2000 | 100.0 | 20.0 | 80.0 | 8.0 | a |
| 2001 | 95.0 | 25.0 | 70.0 | 9.0 | b |
| 2002 | 93.0 | 21.0 | 72.0 | 10.0 | a |
| 2003 | 100.0 | 30.0 | 70.0 | 11.0 | b |
| 2004 | 110.0 | 39.0 | 71.0 | 12.0 | a |
| 2005 | 115.0 | 55.0 | 60.0 | 14.0 | b |
| 2006 | 113.0 | 50.0 | 63.0 | 15.0 | a |
| 2007 | 118.0 | 53.0 | 65.0 | 17.0 | b |
| 2008 | 119.0 | 60.0 | 59.0 | 18.0 | a |
| 2009 | 200.0 | 62.0 | NaN | 20.0 | b |
列conにNaNが残っている。
<注意>
subset=['inv']のように,NaNがあるかを確認する列が1つであってもリスト[]で指定する。複数であれば,次のように列ラベルをリストとして並べれば良い。
subset=['inv','id']
非常に便利な引数なので覚えておこう!
並び替え#
dfの行を並び替えるにはメソッド.sort_values()を使う。引数には,並び替える基準となる列ラベルを指定し,デフォルトでは昇順となる。次のコードではgdpに従って昇順に並び替えている。
df.sort_values('gdp').head()
| gdp | inv | con | pop | id | |
|---|---|---|---|---|---|
| year | |||||
| 2002 | 93.0 | 21.0 | 72.0 | 10.0 | a |
| 2001 | 95.0 | 25.0 | 70.0 | 9.0 | b |
| 2000 | 100.0 | 20.0 | 80.0 | 8.0 | a |
| 2003 | 100.0 | 30.0 | 70.0 | 11.0 | b |
| 2004 | 110.0 | 39.0 | 71.0 | 12.0 | a |
引数ascending=Falseを使うと降順になる。
df.sort_values('gdp', ascending=False).head()
| gdp | inv | con | pop | id | |
|---|---|---|---|---|---|
| year | |||||
| 2010 | 210.0 | NaN | NaN | 21.0 | a |
| 2009 | 200.0 | 62.0 | NaN | 20.0 | b |
| 2008 | 119.0 | 60.0 | 59.0 | 18.0 | a |
| 2007 | 118.0 | 53.0 | 65.0 | 17.0 | b |
| 2005 | 115.0 | 55.0 | 60.0 | 14.0 | b |
複数の列を基準として,昇順と降順を別々に指定することも可能である。
df.sort_values(['id','gdp'], ascending=[True,False]).head()
| gdp | inv | con | pop | id | |
|---|---|---|---|---|---|
| year | |||||
| 2010 | 210.0 | NaN | NaN | 21.0 | a |
| 2008 | 119.0 | 60.0 | 59.0 | 18.0 | a |
| 2006 | 113.0 | 50.0 | 63.0 | 15.0 | a |
| 2004 | 110.0 | 39.0 | 71.0 | 12.0 | a |
| 2000 | 100.0 | 20.0 | 80.0 | 8.0 | a |
ここではidに従って先に並び替えられ,その後にgdpに従って並び替えられている。ascendingは昇順(True)か降順(False)かを指定する引数であり,['id','gdp']とascending=['True','False']の順番が対応している。即ち,idは昇順,gdpは降順となるように並び替えている。
DataFrameの結合#
データを扱うと必ずと言って良いほど必要になるのがデータ・セットの結合である。例えば,日本銀行と米国連邦準備制度(米国の中央銀行)のデータからなるdfを作るとすると,それぞれのサイトから取得したデータ・セットを結合する必要がある。DataFrameには,そのための便利なメソッドが準備されているので,ここではそれを紹介する。
3つの.csvファイルを使う。
url = 'https://raw.githubusercontent.com/Haruyama-KobeU/Py4Basics/master/data/'
df1 = pd.read_csv(url+'data1.csv')
df2 = pd.read_csv(url+'data2.csv')
df3 = pd.read_csv(url+'data3.csv')
df1
| year | gdp | inv | con | pop | id | |
|---|---|---|---|---|---|---|
| 0 | 2000 | 100 | 20.0 | 80.0 | 8 | a |
| 1 | 2001 | 95 | 25.0 | 70.0 | 9 | b |
| 2 | 2002 | 93 | 21.0 | 72.0 | 10 | a |
| 3 | 2003 | 100 | 30.0 | 70.0 | 11 | b |
| 4 | 2004 | 110 | 39.0 | 71.0 | 12 | a |
| 5 | 2005 | 115 | 55.0 | 60.0 | 14 | b |
| 6 | 2006 | 113 | 50.0 | 63.0 | 15 | a |
| 7 | 2007 | 118 | 53.0 | 65.0 | 17 | b |
| 8 | 2008 | 119 | 60.0 | 59.0 | 18 | a |
| 9 | 2009 | 200 | 62.0 | NaN | 20 | b |
| 10 | 2010 | 210 | NaN | NaN | 21 | a |
df2
| year | gnp | id2 | |
|---|---|---|---|
| 0 | 1995 | 101 | 1 |
| 1 | 1996 | 97 | 1 |
| 2 | 1997 | 96 | 1 |
| 3 | 2000 | 103 | 1 |
| 4 | 2001 | 103 | 0 |
| 5 | 2002 | 102 | 0 |
| 6 | 2003 | 105 | 0 |
| 7 | 2004 | 110 | 0 |
df3
| year | gdp | inv | con | pop | id | |
|---|---|---|---|---|---|---|
| 0 | 2011 | 212 | 70 | 142 | 22 | b |
| 1 | 2012 | 215 | 72 | 143 | 23 | a |
| 2 | 2015 | 220 | 80 | 140 | 24 | b |
df3.loc[0,'year']
2011
横結合:merge()#
merge()以外にも結合に使える関数はあるが,ここではmerge()のみを考える。
df1を「左」,df2を「右」に横結合する。
pd.merge(df1, df2, on=None, how='inner')
onはどの列を基準にして結合するかを指定(ここでは「基準列」と呼ぼう)例えば,
df1とdf2の両方にyearの列がある場合,on='year'とすると列yearが基準列となる。df1とdf2の別々の列を指定する場合はleft_on=とright_on=を使う。
基準列に基づいて残す行を決める(
howで説明する)基準列にある要素の順番が合ってなくても,自動でマッチさせる。
複数指定も可
デフォルトは
None
howはonで指定した基準列に基づいてどのように結合するかを指定inner:df1とdf2の両方に基準列ある行だけを残す(デフォルト)。left:df1の行は全て残し,df2からはマッチする行だけが残る(マッチしない行は削除)。またdf1にありdf2にない行にはNaNが入る。right:df2の行は全て残し,df1からはマッチする行だけが残る(マッチしない行は削除)。またdf2にありdf1にない行にはNaNが入る。outer:df1とdf2の両方の行を残し,マッチする行がない場合はNaNを入れる。
(コメント) この他に様々な引数があるのでこのサイトを参照。例えば,場合によっては次の引数を使う必要があるかも知れないので確認しよう。
left_index=True:df1では行インデックスを基準列にする。right_index=True:df2では行インデックスを基準列にする。
例1#
yearを基準列とする。共通する行だけを残す。
pd.merge(df1, df2, on='year', how='inner')
| year | gdp | inv | con | pop | id | gnp | id2 | |
|---|---|---|---|---|---|---|---|---|
| 0 | 2000 | 100 | 20.0 | 80.0 | 8 | a | 103 | 1 |
| 1 | 2001 | 95 | 25.0 | 70.0 | 9 | b | 103 | 0 |
| 2 | 2002 | 93 | 21.0 | 72.0 | 10 | a | 102 | 0 |
| 3 | 2003 | 100 | 30.0 | 70.0 | 11 | b | 105 | 0 |
| 4 | 2004 | 110 | 39.0 | 71.0 | 12 | a | 110 | 0 |
例2#
yearを基準列とする。df1の全ての行を残す。df2ではマッチする行だけ残り,マッチしない行は削除される。df1にありdf2にない行にはNaNが入る。
pd.merge(df1, df2, on='year', how='left')
| year | gdp | inv | con | pop | id | gnp | id2 | |
|---|---|---|---|---|---|---|---|---|
| 0 | 2000 | 100 | 20.0 | 80.0 | 8 | a | 103.0 | 1.0 |
| 1 | 2001 | 95 | 25.0 | 70.0 | 9 | b | 103.0 | 0.0 |
| 2 | 2002 | 93 | 21.0 | 72.0 | 10 | a | 102.0 | 0.0 |
| 3 | 2003 | 100 | 30.0 | 70.0 | 11 | b | 105.0 | 0.0 |
| 4 | 2004 | 110 | 39.0 | 71.0 | 12 | a | 110.0 | 0.0 |
| 5 | 2005 | 115 | 55.0 | 60.0 | 14 | b | NaN | NaN |
| 6 | 2006 | 113 | 50.0 | 63.0 | 15 | a | NaN | NaN |
| 7 | 2007 | 118 | 53.0 | 65.0 | 17 | b | NaN | NaN |
| 8 | 2008 | 119 | 60.0 | 59.0 | 18 | a | NaN | NaN |
| 9 | 2009 | 200 | 62.0 | NaN | 20 | b | NaN | NaN |
| 10 | 2010 | 210 | NaN | NaN | 21 | a | NaN | NaN |
例3#
yearを基準列とする。df2の全ての行を残す。df1ではマッチする行だけ残り,マッチしない行は削除される。df1にありdf2にない行にはNaNが入る。
pd.merge(df1, df2, on='year', how='right')
| year | gdp | inv | con | pop | id | gnp | id2 | |
|---|---|---|---|---|---|---|---|---|
| 0 | 1995 | NaN | NaN | NaN | NaN | NaN | 101 | 1 |
| 1 | 1996 | NaN | NaN | NaN | NaN | NaN | 97 | 1 |
| 2 | 1997 | NaN | NaN | NaN | NaN | NaN | 96 | 1 |
| 3 | 2000 | 100.0 | 20.0 | 80.0 | 8.0 | a | 103 | 1 |
| 4 | 2001 | 95.0 | 25.0 | 70.0 | 9.0 | b | 103 | 0 |
| 5 | 2002 | 93.0 | 21.0 | 72.0 | 10.0 | a | 102 | 0 |
| 6 | 2003 | 100.0 | 30.0 | 70.0 | 11.0 | b | 105 | 0 |
| 7 | 2004 | 110.0 | 39.0 | 71.0 | 12.0 | a | 110 | 0 |
例4#
yearを基準列とする。df1とdf2の全ての行は残る。df1にありdf2にない行にはNaNが入る。df2にありdf1にない行にはNaNが入る。
pd.merge(df1, df2, on='year', how='outer')
| year | gdp | inv | con | pop | id | gnp | id2 | |
|---|---|---|---|---|---|---|---|---|
| 0 | 1995 | NaN | NaN | NaN | NaN | NaN | 101.0 | 1.0 |
| 1 | 1996 | NaN | NaN | NaN | NaN | NaN | 97.0 | 1.0 |
| 2 | 1997 | NaN | NaN | NaN | NaN | NaN | 96.0 | 1.0 |
| 3 | 2000 | 100.0 | 20.0 | 80.0 | 8.0 | a | 103.0 | 1.0 |
| 4 | 2001 | 95.0 | 25.0 | 70.0 | 9.0 | b | 103.0 | 0.0 |
| 5 | 2002 | 93.0 | 21.0 | 72.0 | 10.0 | a | 102.0 | 0.0 |
| 6 | 2003 | 100.0 | 30.0 | 70.0 | 11.0 | b | 105.0 | 0.0 |
| 7 | 2004 | 110.0 | 39.0 | 71.0 | 12.0 | a | 110.0 | 0.0 |
| 8 | 2005 | 115.0 | 55.0 | 60.0 | 14.0 | b | NaN | NaN |
| 9 | 2006 | 113.0 | 50.0 | 63.0 | 15.0 | a | NaN | NaN |
| 10 | 2007 | 118.0 | 53.0 | 65.0 | 17.0 | b | NaN | NaN |
| 11 | 2008 | 119.0 | 60.0 | 59.0 | 18.0 | a | NaN | NaN |
| 12 | 2009 | 200.0 | 62.0 | NaN | 20.0 | b | NaN | NaN |
| 13 | 2010 | 210.0 | NaN | NaN | 21.0 | a | NaN | NaN |
縦結合#
concat()は横結合にも使えるが,縦結合のみ考える。
引数には複数のDataFrameをリストとして書く。
df13 = pd.concat([df1,df3])
df13.tail()
| year | gdp | inv | con | pop | id | |
|---|---|---|---|---|---|---|
| 9 | 2009 | 200 | 62.0 | NaN | 20 | b |
| 10 | 2010 | 210 | NaN | NaN | 21 | a |
| 0 | 2011 | 212 | 70.0 | 142.0 | 22 | b |
| 1 | 2012 | 215 | 72.0 | 143.0 | 23 | a |
| 2 | 2015 | 220 | 80.0 | 140.0 | 24 | b |
その他#
インデックスを振り直す#
メソッド.reset_index()を使うと,行のインデックスを0,1,2,..と振り直すことができる。df13を使い説明する。
df13.reset_index()
| index | year | gdp | inv | con | pop | id | |
|---|---|---|---|---|---|---|---|
| 0 | 0 | 2000 | 100 | 20.0 | 80.0 | 8 | a |
| 1 | 1 | 2001 | 95 | 25.0 | 70.0 | 9 | b |
| 2 | 2 | 2002 | 93 | 21.0 | 72.0 | 10 | a |
| 3 | 3 | 2003 | 100 | 30.0 | 70.0 | 11 | b |
| 4 | 4 | 2004 | 110 | 39.0 | 71.0 | 12 | a |
| 5 | 5 | 2005 | 115 | 55.0 | 60.0 | 14 | b |
| 6 | 6 | 2006 | 113 | 50.0 | 63.0 | 15 | a |
| 7 | 7 | 2007 | 118 | 53.0 | 65.0 | 17 | b |
| 8 | 8 | 2008 | 119 | 60.0 | 59.0 | 18 | a |
| 9 | 9 | 2009 | 200 | 62.0 | NaN | 20 | b |
| 10 | 10 | 2010 | 210 | NaN | NaN | 21 | a |
| 11 | 0 | 2011 | 212 | 70.0 | 142.0 | 22 | b |
| 12 | 1 | 2012 | 215 | 72.0 | 143.0 | 23 | a |
| 13 | 2 | 2015 | 220 | 80.0 | 140.0 | 24 | b |
この例では元のインデックスが列indexとして追加されている。reset_index()に引数drop=Trueを加えると,列indexは追加されない。
df13.reset_index(drop=True).head()
| year | gdp | inv | con | pop | id | |
|---|---|---|---|---|---|---|
| 0 | 2000 | 100 | 20.0 | 80.0 | 8 | a |
| 1 | 2001 | 95 | 25.0 | 70.0 | 9 | b |
| 2 | 2002 | 93 | 21.0 | 72.0 | 10 | a |
| 3 | 2003 | 100 | 30.0 | 70.0 | 11 | b |
| 4 | 2004 | 110 | 39.0 | 71.0 | 12 | a |
列のラベルの変更#
メソッド.rename()を使い列のラベルを変更する。引数は次の形で設定する。
ここで「辞書」は次のルールで指定する。
key:元のラベルvalue:新しいラベル
下のコードでは,df13を使い新しいラベルとしてpop_newとid_newを使っている。
df13.rename(columns={'pop':'pop_new','id':'id_new'}).head()
| year | gdp | inv | con | pop_new | id_new | |
|---|---|---|---|---|---|---|
| 0 | 2000 | 100 | 20.0 | 80.0 | 8 | a |
| 1 | 2001 | 95 | 25.0 | 70.0 | 9 | b |
| 2 | 2002 | 93 | 21.0 | 72.0 | 10 | a |
| 3 | 2003 | 100 | 30.0 | 70.0 | 11 | b |
| 4 | 2004 | 110 | 39.0 | 71.0 | 12 | a |
.rename()以外にリストを使って列ラベルを変更することも可能である。例えば,
df.columns = ['year', 'gdp', 'inv', 'con', 'pop_new', 'id_new']
この場合,列の数とリストの要素数が合わないとエラーとなるので注意しよう。
列の並び替え#
アルファベット順#
メソッド.sort_index()を使い,引数にはaxis='columns'もしくはaxis=1を指定する。
(コメント)引数がaxis='rows'もしくはaxis=0の場合,行が並び替えられる。
df13.sort_index(axis='columns').head()
| con | gdp | id | inv | pop | year | |
|---|---|---|---|---|---|---|
| 0 | 80.0 | 100 | a | 20.0 | 8 | 2000 |
| 1 | 70.0 | 95 | b | 25.0 | 9 | 2001 |
| 2 | 72.0 | 93 | a | 21.0 | 10 | 2002 |
| 3 | 70.0 | 100 | b | 30.0 | 11 | 2003 |
| 4 | 71.0 | 110 | a | 39.0 | 12 | 2004 |
順番を指定する#
方法1#
列を選択する方法を使い並び替える。
var = ['id','year','gdp','con','inv','pop']
df13.loc[:,var].head()
| id | year | gdp | con | inv | pop | |
|---|---|---|---|---|---|---|
| 0 | a | 2000 | 100 | 80.0 | 20.0 | 8 |
| 1 | b | 2001 | 95 | 70.0 | 25.0 | 9 |
| 2 | a | 2002 | 93 | 72.0 | 21.0 | 10 |
| 3 | b | 2003 | 100 | 70.0 | 30.0 | 11 |
| 4 | a | 2004 | 110 | 71.0 | 39.0 | 12 |
方法2#
次の列の選択方法でも可。
df13[var].head()
| id | year | gdp | con | inv | pop | |
|---|---|---|---|---|---|---|
| 0 | a | 2000 | 100 | 80.0 | 20.0 | 8 |
| 1 | b | 2001 | 95 | 70.0 | 25.0 | 9 |
| 2 | a | 2002 | 93 | 72.0 | 21.0 | 10 |
| 3 | b | 2003 | 100 | 70.0 | 30.0 | 11 |
| 4 | a | 2004 | 110 | 71.0 | 39.0 | 12 |
方法3#
メソッド.reindex()を使う。引数はcolumns=[]。
df13.reindex(columns=['id','year','gdp','con','inv','pop']).head()
| id | year | gdp | con | inv | pop | |
|---|---|---|---|---|---|---|
| 0 | a | 2000 | 100 | 80.0 | 20.0 | 8 |
| 1 | b | 2001 | 95 | 70.0 | 25.0 | 9 |
| 2 | a | 2002 | 93 | 72.0 | 21.0 | 10 |
| 3 | b | 2003 | 100 | 70.0 | 30.0 | 11 |
| 4 | a | 2004 | 110 | 71.0 | 39.0 | 12 |
方法3の応用#
最後の行を最初に移動する。
.columns.tolist():コラムのラベルを取得し,それをリストに変換[col[-1]]+col[0:-2]の分解と結合[col[-1]]:colの最後の要素を抽出するが,文字列として返されるので(外側の)[ ]を使ってリストに変換col[0:-2]:colの最初から最後から二番目の要素をリストとして取得+:リストの結合
col = df13.columns.tolist()
new_col = [col[-1]]+col[0:-2]
df.reindex(columns=new_col).head()
| id | year | gdp | inv | con | |
|---|---|---|---|---|---|
| year | |||||
| 2000 | a | NaN | 100.0 | 20.0 | 80.0 |
| 2001 | b | NaN | 95.0 | 25.0 | 70.0 |
| 2002 | a | NaN | 93.0 | 21.0 | 72.0 |
| 2003 | b | NaN | 100.0 | 30.0 | 70.0 |
| 2004 | a | NaN | 110.0 | 39.0 | 71.0 |