Python pandasで2次元リスト同士の組み合わせを列挙する
2020/03/17 categories:Python| tags:Python|Pandas|
複数のリストから組み合わせを列挙したpandas.DataFrameを作成しようとしたときに意外とはまったのでメモしておきます。
実現したいこと
例えば下記2つのリストa、bがあった場合
a = [[11,12],[21,22],[31,32]]
b = [[41,42],[51,52],[61,62]]
下記のような組み合わせを列挙したpandasのDataFrameが欲しいとします
0 1 0 1
0 11 12 41 42
1 11 12 51 52
2 11 12 61 62
3 21 22 41 42
4 21 22 51 52
5 21 22 61 62
6 31 32 41 42
7 31 32 51 52
8 31 32 61 62
試したこと
まずはitertools.productで直積を求めます
import itertools
import pandas as pd
a = [[11,12],[21,22],[31,32]]
b = [[41,42],[51,52],[61,62]]
d = list(itertools.product(a, b))
for i in d:
print(i)
実行結果はタプルの組み合わせとなります
([11, 12], [41, 42])
([11, 12], [51, 52])
([11, 12], [61, 62])
([21, 22], [41, 42])
([21, 22], [51, 52])
([21, 22], [61, 62])
([31, 32], [41, 42])
([31, 32], [51, 52])
([31, 32], [61, 62])
この結果からそのままDataFrameを作成してもリストを含むDataFrameになってしまいます
import itertools
import pandas as pd
a = [[11,12],[21,22],[31,32]]
b = [[41,42],[51,52],[61,62]]
d = list(itertools.product(a, b))
df = pd.DataFrame(d)
print(df)
結果
0 1
0 [11, 12] [41, 42]
1 [11, 12] [51, 52]
2 [11, 12] [61, 62]
3 [21, 22] [41, 42]
4 [21, 22] [51, 52]
5 [21, 22] [61, 62]
6 [31, 32] [41, 42]
7 [31, 32] [51, 52]
8 [31, 32] [61, 62]
解決策
この結果のDataFrameの列をリストに変換すると2次元リストになるので、その2次元リストからDataFrameを作成すると欲しい結果が得られそうです
import itertools
import pandas as pd
a = [[11,12],[21,22],[31,32]]
b = [[41,42],[51,52],[61,62]]
d = list(itertools.product(a, b))
df = pd.DataFrame(d)
ls_a = pd.DataFrame(df[0].tolist())
ls_b = pd.DataFrame(df[1].tolist())
print(ls_a)
print(ls_b)
結果
0 1
0 11 12
1 11 12
2 11 12
3 21 22
4 21 22
5 21 22
6 31 32
7 31 32
8 31 32
0 1
0 41 42
1 51 52
2 61 62
3 41 42
4 51 52
5 61 62
6 41 42
7 51 52
8 61 62
最後にこの2つのDataFrameを横方向に連結すると欲しい結果が得られました
import itertools
import pandas as pd
a = [[11,12],[21,22],[31,32]]
b = [[41,42],[51,52],[61,62]]
d = list(itertools.product(a, b))
df = pd.DataFrame(d)
ls_a = pd.DataFrame(df[0].tolist())
ls_b = pd.DataFrame(df[1].tolist())
cc = pd.concat([ls_a, ls_b], axis=1)
print(cc)
結果
0 1 0 1
0 11 12 41 42
1 11 12 51 52
2 11 12 61 62
3 21 22 41 42
4 21 22 51 52
5 21 22 61 62
6 31 32 41 42
7 31 32 51 52
8 31 32 61 62
リストが3つの場合
リストを3つに増やしても同様の結果が得られます
## -*- coding: utf-8 -*-
import itertools
import pandas as pd
a = [[11,12],[21,22]]
b = [[31,32],[41,42]]
c = [[51,52],[61,62]]
d = list( itertools.product(a, b, c) )
df = pd.DataFrame(d)
ls_a = pd.DataFrame(df[0].tolist())
ls_b = pd.DataFrame(df[1].tolist())
ls_c = pd.DataFrame(df[2].tolist())
cc = pd.concat([ls_a, ls_b, ls_c], axis=1)
print(cc)
結果
0 1 0 1 0 1
0 11 12 31 32 51 52
1 11 12 31 32 61 62
2 11 12 41 42 51 52
3 11 12 41 42 61 62
4 21 22 31 32 51 52
5 21 22 31 32 61 62
6 21 22 41 42 51 52
7 21 22 41 42 61 62