Python pandasで2次元リスト同士の組み合わせを列挙する

Share on:

複数のリストから組み合わせを列挙したpandas.DataFrameを作成しようとしたときに意外とはまったのでメモしておきます。

実現したいこと

例えば下記2つのリストa、bがあった場合

1a = [[11,12],[21,22],[31,32]]
2b = [[41,42],[51,52],[61,62]]

下記のような組み合わせを列挙したpandasのDataFrameが欲しいとします

 1    0   1   0   1
 20  11  12  41  42
 31  11  12  51  52
 42  11  12  61  62
 53  21  22  41  42
 64  21  22  51  52
 75  21  22  61  62
 86  31  32  41  42
 97  31  32  51  52
108  31  32  61  62

試したこと

まずはitertools.productで直積を求めます

1import itertools
2import pandas as pd
3a = [[11,12],[21,22],[31,32]]
4b = [[41,42],[51,52],[61,62]]
5d = list(itertools.product(a, b))
6for i in d:
7    print(i)

実行結果はタプルの組み合わせとなります

1([11, 12], [41, 42])
2([11, 12], [51, 52])
3([11, 12], [61, 62])
4([21, 22], [41, 42])
5([21, 22], [51, 52])
6([21, 22], [61, 62])
7([31, 32], [41, 42])
8([31, 32], [51, 52])
9([31, 32], [61, 62])

この結果からそのままDataFrameを作成してもリストを含むDataFrameになってしまいます

1import itertools
2import pandas as pd
3a = [[11,12],[21,22],[31,32]]
4b = [[41,42],[51,52],[61,62]]
5d = list(itertools.product(a, b))
6df = pd.DataFrame(d)
7print(df)

結果

 1          0         1
 20  [11, 12]  [41, 42]
 31  [11, 12]  [51, 52]
 42  [11, 12]  [61, 62]
 53  [21, 22]  [41, 42]
 64  [21, 22]  [51, 52]
 75  [21, 22]  [61, 62]
 86  [31, 32]  [41, 42]
 97  [31, 32]  [51, 52]
108  [31, 32]  [61, 62]

解決策

この結果のDataFrameの列をリストに変換すると2次元リストになるので、その2次元リストからDataFrameを作成すると欲しい結果が得られそうです

 1import itertools
 2import pandas as pd
 3a = [[11,12],[21,22],[31,32]]
 4b = [[41,42],[51,52],[61,62]]
 5d = list(itertools.product(a, b))
 6df = pd.DataFrame(d)
 7ls_a = pd.DataFrame(df[0].tolist())
 8ls_b = pd.DataFrame(df[1].tolist())
 9print(ls_a)
10print(ls_b)

結果

 1    0   1
 20  11  12
 31  11  12
 42  11  12
 53  21  22
 64  21  22
 75  21  22
 86  31  32
 97  31  32
108  31  32
11    0   1
120  41  42
131  51  52
142  61  62
153  41  42
164  51  52
175  61  62
186  41  42
197  51  52
208  61  62

最後にこの2つのDataFrameを横方向に連結すると欲しい結果が得られました

 1import itertools
 2import pandas as pd
 3a = [[11,12],[21,22],[31,32]]
 4b = [[41,42],[51,52],[61,62]]
 5d = list(itertools.product(a, b))
 6df = pd.DataFrame(d)
 7ls_a = pd.DataFrame(df[0].tolist())
 8ls_b = pd.DataFrame(df[1].tolist())
 9cc = pd.concat([ls_a, ls_b], axis=1)
10print(cc)

結果

 1    0   1   0   1
 20  11  12  41  42
 31  11  12  51  52
 42  11  12  61  62
 53  21  22  41  42
 64  21  22  51  52
 75  21  22  61  62
 86  31  32  41  42
 97  31  32  51  52
108  31  32  61  62

リストが3つの場合

リストを3つに増やしても同様の結果が得られます

 1# -*- coding: utf-8 -*-
 2import itertools
 3import pandas as pd
 4a = [[11,12],[21,22]]
 5b = [[31,32],[41,42]]
 6c = [[51,52],[61,62]]
 7d = list( itertools.product(a, b, c) )
 8df = pd.DataFrame(d)
 9ls_a = pd.DataFrame(df[0].tolist())
10ls_b = pd.DataFrame(df[1].tolist())
11ls_c = pd.DataFrame(df[2].tolist())
12cc = pd.concat([ls_a, ls_b, ls_c], axis=1)
13print(cc)

結果

1    0   1   0   1   0   1
20  11  12  31  32  51  52
31  11  12  31  32  61  62
42  11  12  41  42  51  52
53  11  12  41  42  61  62
64  21  22  31  32  51  52
75  21  22  31  32  61  62
86  21  22  41  42  51  52
97  21  22  41  42  61  62

関連記事