pandas.DataFrame, SeriesとPythonのリストを相互に変換
pandasのDataFrame
, Series
とPython組み込みのリストlist
を相互に変換する方法を説明する。
なお、便宜上「変換」という言葉を使っているが、実際は元のオブジェクトはそのままで新たな型のオブジェクトが生成される。
DataFrame
, Series
とNumPy配列ndarray
の相互変換、DataFrame
とSeries
の相互変換については以下の記事を参照。
本記事のサンプルコードのpandasのバージョンは以下の通り。バージョンによって仕様が異なる可能性があるので注意。
import pandas as pd
print(pd.__version__)
# 2.1.4
リストをpandasのDataFrame, Seriesに変換
pd.DataFrame(), pd.Series()でリストをDataFrame, Seriesに変換
コンストラクタpd.Series()
, pd.DataFrame()
の第一引数にリストを指定すると、そのリストを元にSeries
, DataFrame
が生成される。
l_1d = [0, 10, 20]
print(pd.Series(l_1d))
# 0 0
# 1 10
# 2 20
# dtype: int64
l_2d = [[0, 10, 20], [30, 40, 50]]
print(pd.DataFrame(l_2d))
# 0 1 2
# 0 0 10 20
# 1 30 40 50
pd.DataFrame()
に一次元リストをそのまま指定すると一列のDataFrame
、[一次元リスト]
として指定すると一行のDataFrame
が生成される。
print(pd.DataFrame(l_1d))
# 0
# 0 0
# 1 10
# 2 20
print(pd.DataFrame([l_1d]))
# 0 1 2
# 0 0 10 20
二次元リストの行・列を入れ替えたい場合は、転置して指定する。
print(pd.DataFrame(zip(*l_2d)))
# 0 1
# 0 0 30
# 1 10 40
# 2 20 50
行名・列名の指定: 引数index, columns
引数index
で行名(行ラベル)、引数columns
で列名(列ラベル)を指定できる。
print(pd.Series(l_1d, index=['X', 'Y', 'Z']))
# X 0
# Y 10
# Z 20
# dtype: int64
print(pd.DataFrame(l_2d, index=['X', 'Y'], columns=['A', 'B', 'C']))
# A B C
# X 0 10 20
# Y 30 40 50
Series
, DataFrame
を生成したあとで行名・列名を設定・変更することも可能。
データ型の指定: 引数dtype
DataFrame
の各列およびSeries
のデータ型dtype
は、リストの値から自動的に決まる。
例えば、整数int
と浮動小数点数float
が混在する列のデータ型はfloat
、数値と文字列が混在する列のデータ型はobject
となる。
l_2d_multi = [[0, 0.0, 'abc', 123, 'abc'], [10, 0.1, 'xyz', 1.23, 100]]
print(pd.DataFrame(l_2d_multi))
# 0 1 2 3 4
# 0 0 0.0 abc 123.00 abc
# 1 10 0.1 xyz 1.23 100
print(pd.DataFrame(l_2d_multi).dtypes)
# 0 int64
# 1 float64
# 2 object
# 3 float64
# 4 object
# dtype: object
pd.DataFrame()
, pd.Series()
の引数dtype
でデータ型を指定して生成することもできる。
print(pd.DataFrame(l_2d, dtype=float))
# 0 1 2
# 0 0.0 10.0 20.0
# 1 30.0 40.0 50.0
pandasのデータ型についての詳細は以下の記事を参照。
ラベル(行名・列名)を含むリストの場合
ラベルと値のペアのリストからSeries
を生成するには、ラベルと値に分解してpd.Series()
に渡す。
l_1d_index = [['X', 0], ['Y', 1], ['Z', 2]]
index, values = zip(*l_1d_index)
print(index)
# ('X', 'Y', 'Z')
print(values)
# (0, 1, 2)
print(pd.Series(values, index=index))
# X 0
# Y 1
# Z 2
# dtype: int64
ラベルと複数の値からなるリストからDataFrame
を生成するには、全体を読み込んでからset_index()
メソッドでindex
を指定する。
l_2d_index = [['X', 0, 0.0], ['Y', 1, 0.1], ['Z', 2, 0.2]]
df_index = pd.DataFrame(l_2d_index, columns=['idx', 'A', 'B'])
print(df_index)
# idx A B
# 0 X 0 0.0
# 1 Y 1 0.1
# 2 Z 2 0.2
print(df_index.set_index('idx'))
# A B
# idx
# X 0 0.0
# Y 1 0.1
# Z 2 0.2
元のリストに列名も含まれている場合、最初の行を引数columns
、二行目以降を第一引数に指定する。二行目以降はスライスで取得可能。
l_2d_index_columns = [['idx', 'A', 'B'], ['X', 0, 0.0], ['Y', 1, 0.1], ['Z', 2, 0.2]]
df_index_columns = pd.DataFrame(l_2d_index_columns[1:], columns=l_2d_index_columns[0])
print(df_index_columns)
# idx A B
# 0 X 0 0.0
# 1 Y 1 0.1
# 2 Z 2 0.2
print(df_index_columns.set_index('idx'))
# A B
# idx
# X 0 0.0
# Y 1 0.1
# Z 2 0.2
pandasのDataFrame, Seriesをリストに変換
Seriesのtolist(), to_list()メソッドでリストに変換
Series
はtolist()
またはto_list()
メソッドでデータ列をリストに変換できる。
- pandas.Series.tolist — pandas 2.1.4 documentation
- pandas.Series.to_list — pandas 2.1.4 documentation
s = pd.Series([0, 10, 20])
print(s)
# 0 0
# 1 10
# 2 20
# dtype: int64
print(s.tolist())
# [0, 10, 20]
print(s.to_list())
# [0, 10, 20]
DataFrameのvalues属性とndarrayのtolist()メソッドでリストに変換
pandas 2.1.4時点でDataFrame
にはtolist()
やto_list()
メソッドはない。values
属性でNumPy配列ndarray
に変換し、ndarray
のtolist()
メソッドでリストに変換する。
df = pd.DataFrame([[0, 10, 20], [30, 40, 50]])
print(df)
# 0 1 2
# 0 0 10 20
# 1 30 40 50
print(df.values.tolist())
# [[0, 10, 20], [30, 40, 50]]
index, columnsを含めてリストに変換
行名index
もリストのデータとして残すには、reset_index()
メソッドでindex
をリセットしてデータ列にする。
s_index = pd.Series([0, 1, 2], index=['X', 'Y', 'Z'])
print(s_index)
# X 0
# Y 1
# Z 2
# dtype: int64
print(s_index.reset_index())
# index 0
# 0 X 0
# 1 Y 1
# 2 Z 2
print(s_index.reset_index().values.tolist())
# [['X', 0], ['Y', 1], ['Z', 2]]
df_index = pd.DataFrame([[0, 1, 2], [3, 4, 5]], index=['A', 'B'], columns=['X', 'Y', 'Z'])
print(df_index)
# X Y Z
# A 0 1 2
# B 3 4 5
print(df_index.reset_index())
# index X Y Z
# 0 A 0 1 2
# 1 B 3 4 5
print(df_index.reset_index().values.tolist())
# [['A', 0, 1, 2], ['B', 3, 4, 5]]
pandas 2.1.4時点で列名columns
をリセットするメソッドはない。DataFrame
で行名も列名もリストのデータとして残すには、reset_index()
を適用したあと.T
で転置して再度reset_index()
を適用し、さらに.T
で元に戻す。もっといい方法があるかもしれない。
print(df_index.reset_index().T.reset_index().T.values.tolist())
# [['index', 'X', 'Y', 'Z'], ['A', 0, 1, 2], ['B', 3, 4, 5]]
index, columnsをリストに変換
Series
のindex
属性、および、DataFrame
のindex
, columns
属性はいずれもIndex
型。tolist()
またはto_list()
メソッドでリストに変換できる。
s_index = pd.Series([0, 1, 2], index=['X', 'Y', 'Z'])
print(s_index)
# X 0
# Y 1
# Z 2
# dtype: int64
print(s_index.index)
# Index(['X', 'Y', 'Z'], dtype='object')
print(s_index.index.tolist())
# ['X', 'Y', 'Z']
df_index = pd.DataFrame([[0, 1, 2], [3, 4, 5]], index=['A', 'B'], columns=['X', 'Y', 'Z'])
print(df_index)
# X Y Z
# A 0 1 2
# B 3 4 5
print(df_index.index)
# Index(['A', 'B'], dtype='object')
print(df_index.index.tolist())
# ['A', 'B']
print(df_index.columns)
# Index(['X', 'Y', 'Z'], dtype='object')
print(df_index.columns.tolist())
# ['X', 'Y', 'Z']
なお、Index
型はそのままfor文で要素を取り出したり、[]
で位置を指定して要素を取得したりできる。スライスも使えるが、要素の変更はできない。要素を取得するだけならリストに変換する必要はない。
for i in df_index.columns:
print(i, type(i))
# X <class 'str'>
# Y <class 'str'>
# Z <class 'str'>
print(df_index.columns[0])
# X
print(df_index.columns[:2])
# Index(['X', 'Y'], dtype='object')
# df_index.columns[0] = 'x'
# TypeError: Index does not support mutable operations