いきなり答える備忘録

Google Workspace・Microsoft 365・LibreOfficeなどに関するメモ

(Excel)複数のリストから組み合わせを全通り生成する方法

 Excelで、2つのリストから組み合わせをすべて列挙する方法です。クロス結合とか直積とも呼ばれます。
 いずれの方法も最近導入された新しい関数や機能が必要となりますが、Python in Excelを使う方法なら3つ以上のリストからも容易にすべての組み合わせを生成できます。

TOCOL/TEXTBEFORE関数等を使う方法

 文字列関数(TEXTBEFORE/TEXTAFTER)を利用する方法です。
 画像ではB列には3つの野菜が、C列には4つの果物が入力されています。
 これに対しF3セルに次のような式を入力して、すべての組み合わせを表す12個の行を出力しています。

 F3セル

=LET(x,TOCOL(B3:B5&"_"&TRANSPOSE(C3:C6)),
HSTACK(TEXTBEFORE(x,"_"),TEXTAFTER(x,"_"))
)

 「B3:B5&"_"&TRANSPOSE(C3:C6)」の部分で、野菜と果物の名前を「_」でつないだ文字列を全通り(12個)生成しています(下記参照)。
 そしてこれをTOCOL関数で縦1列に並べたものをLET関数によりxと名付けています。
 さらにTEXTBEFORE関数とTEXTAFTER関数により、xの各項目を「_」の前後に分割した列をそれぞれ生成し、HSTACK関数で横並びに表示しています。
 TEXTSPLIT関数が使えればもっと簡単なのですが、TEXTSPLIT関数の第1引数に配列を与えた場合には最初の項目(この例では野菜の名前)しか返ってこないためうまくいきません。



 「B3:B5&"_"&TRANSPOSE(C3:C6)」の部分だけ実行すると次のようになります。
 これを縦に並べ替えて「_」の前後で左右に区切ることで、上の画像の結果になることがわかると思います。

 


 C列の側にTRANSPOSE関数を適用すると、果物の初出順が優先されたソートとなります。

 F3セル

=LET(x,TOCOL(TRANSPOSE(B3:B5)&"_"&C3:C6),
HSTACK(TEXTBEFORE(x,"_"),TEXTAFTER(x,"_"))
)

 


 なお、文字列関数を使っているため数値は文字に変換されます。
 そこで次の画像では対症療法としてVALUE関数を使い、文字列に変換された数字を再度数値に変換しています。

 F3セル

=LET(x,TOCOL(B3:B5&"_"&TRANSPOSE(C3:C6)),
HSTACK(TEXTBEFORE(x,"_"),VALUE(TEXTAFTER(x,"_")))
)

Python in Excelを使う方法

 2024年秋に導入されたPython in Excelを利用する方法です。
 次の画像では、上記例と同様に2つのリストから全通り(12個)の組み合わせを生成しています。

 F3セル(Python in Excel)

import itertools

a = xl("B3:B5").unstack()
b = xl("C3:C6").unstack()
list(itertools.product(a, b))

 入力手順は次のようになります(2,3は順不同)。

  1. B3セルに「=PY(」と入力、または数式タブから「Pythonの挿入」を選択してセルを変化させる。
  2. 数式バーの左にあるアイコンをクリックして「Excelの値」を選択(に変わる)
  3. 上記の式を入力してCtrl+Enterで確定する。

 コードの説明ですが、繰り返し処理に便利なitertoolsモジュールを使っています。
 参照したセルのデータをunstackでフラットな1次元データにし(pandas.DataFrame→Series)、組み合わせを生成するitertools.permutationsを適用しています。



 この方法のメリットとしてコードが簡単なこと、3つ以上のリストにも対応できること、数値がそのまま出力されることが挙げられます。
 次の画像では3つのリストから全通り(2*3*2=12個)の組み合わせを生成しています。数値もそのまま出力されています。

 F3セル(Python in Excel)

import itertools

a = xl("B3:B4").unstack()
b = xl("C3:C5").unstack()
c = xl("D3:D4").unstack()
list(itertools.product(a, b, c))