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

複数のリストから組み合わせを列挙した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

コメント

タイトルとURLをコピーしました