Power Query로 순열 출력

순열이 몇 가지인지를 요구하는 것이 아니라, 실제로 그 전체대로를 발생시키는 시도입니다.
이른바 크로스 결합 처리를 한 후, 좁히는 공정으로 만들고 있습니다.
수중의 PC(메모리 4GB, Celeron)라면, 요소 9개로부터 9개를 선택하는 순열로, 프리뷰가 돌려주는데 1분 반 정도 걸렸습니다. 이런 걸까요

코드



아래 코드를 빈 쿼리에 붙여넣고 'fx_순열'이라는 이름을 지정합니다.

fx_순열
(InputList as list, NumberOfTimesToSelect as number)=>

if not List.Contains({1..List.Count(InputList)},NumberOfTimesToSelect) then
    "Error:NumberOfTimesToSelectは、1からInputListの要素数までの整数で入力してください。"

else
    let
        Source = Table.FromColumns({InputList}),
        クロス結合 =List.Last(List.Generate(()=>[id=0,tbl =Source],
                                           each [id]<NumberOfTimesToSelect,//―――「NumberOfTimesToSelect-1」だけ列追加するため。
                                           each [id=[id]+1,
                                                 Name="Column"&Number.ToText(id+1),
                                                 Added =Table.AddColumn([tbl],Name,each InputList),
                                                 tbl=Table.ExpandListColumn(Added,Name)],
                                           each [tbl]
                             )
                    ),
        整理 = Table.SelectRows( クロス結合, each List.Union({InputList,Record.ToList(_)})=InputList ),
        重複削除 =Table.Distinct(整理)
    in
        重複削除

실행 예 1: 인수에 중복이 없는 경우



빨강, 파랑, 녹색, 노랑, 흰색의 5개의 순열, 조합을 내 보자.
함수는 아래 코드를 빈 쿼리에 넣습니다.
fx_順列({"赤","青","緑","黄","白"},5)

↓실행 결과. 제대로 5의 계승으로 120행이 되네요.


실행 예 2: 인수에 동일한 것이 있는 경우



시험에 빨강, 파랑, 녹색, 흰색, 흰색에서 5개의 순열, 조합을 내 보자.
fx_順列({"赤","青","緑","白","白"},5)

↓실행 결과. 중복이 있는 만큼 줄어듭니다. (이 경우는 2의 계승만 중복이 있으므로, 그것으로 나누게 된다)
※요소에 중복이 있는 케이스의 공식 등 기억하지 않으므로, 흥미가 있는 분은 조사해 보세요. 다른 경우에도 아마 결과는 맞습니다.


해설



「크로스 결합」의 개소



열 추가로 인수에 넣은 목록을 넣고 확장하는 단순한 반복입니다.
개수가 정해져 있으면, 커스텀 열 추가로 해당 리스트를 넣어, 전개한다고 하는 수작업이어도 좋을 것입니다.

「정리」의 개소



Table.SelectRows의 두 번째 인수(condition)는 테이블의 행 값(Record 형식)을 인수로 한 함수의 형태로 씁니다. Record 형 그대로는 List.Union 함수에 건네줄 수 없기 때문에, Record.ToList 함수로 리스트로 변환하고 있습니다.

List.Union 함수는, 그 행의 값이 InputList 의 요소만으로 성립하고 있는지를 판정하는데 사용했습니다.
List.Union 함수의 거동은 아래와 같습니다.
List.Union({{1,1,1,2,2},{2,1,1}})
//第1引数の範囲に収まるので、 {1,1,1,2,2}が返る。

List.Union({{1,2,2,2},{2,1,1}})
//第1引数には1が1個しかないので、 {1,2,2,2,1}とおしりに追加される。

기타 참고
Record.ToList 함수: Microsoft Docs
Table.Distinct(List.Distinct) 사용 예 | qiita

좋은 웹페이지 즐겨찾기