내 머리를 감쌀 수 없었던 한 가지는 Flatten가 두 번째 인수로 행렬이 제공되며 Mathematica 도움말은 “이 문제에 특히 좋지 않습니다.

Flatten Mathematica 문서 :

Flatten[list, {{s11, s12, ...}, {s21, s22, ...}, ...}] 

list 모든 레벨 $ s_ {ij} $를 결합하여 결과에서 각 레벨을 $ i $로 만듭니다.

누군가 이것이 실제 의미 / 의미에 대해 자세히 설명해 주시겠습니까?

답변

하나 두 번째 인수와 함께 Flatten를 생각하는 편리한 방법은 비정규 (불규칙) 목록에 대해 Transpose와 같은 작업을 수행한다는 것입니다. 다음은 간단한 예 :

In[63]:= Flatten[{{1,2,3},{4,5},{6,7},{8,9,10}},{{2},{1}}] Out[63]= {{1,4,6,8},{2,5,7,9},{3,10}} 

일어나는 것은 원본 목록의 uted 레벨 1은 이제 결과에서 레벨 2의 구성 요소이며 그 반대의 경우도 마찬가지입니다. 이것이 바로 Transpose가하는 일이지만 불규칙한 목록에 대해 수행됩니다. 그러나 위치에 대한 일부 정보가 여기에서 손실되므로 연산을 직접 역으로 바꿀 수 없습니다.

In[65]:= Flatten[{{1,4,6,8},{2,5,7,9},{3,10}},{{2},{1}}] Out[65]= {{1,2,3},{4,5,10},{6,7},{8,9}} 

올바르게 되돌리려면 다음을 수행해야합니다. 다음과 같이 할 수 있습니다.

In[67]:= Flatten/@Flatten[{{1,4,6,8},{2,5,7,9},{3,{},{},10}},{{2},{1}}] Out[67]= {{1,2,3},{4,5},{6,7},{8,9,10}} 

더 흥미로운 예는 더 깊은 중첩이있는 경우입니다.

In[68]:= Flatten[{{{1,2,3},{4,5}},{{6,7},{8,9,10}}},{{2},{1},{3}}] Out[68]= {{{1,2,3},{6,7}},{{4,5},{8,9,10}}} 

다시 여기에서 Flatten가 처음 2 개 수준에서 조각을 교환하면서 (일반화) Transpose처럼 효과적으로 작동했음을 알 수 있습니다. . 다음은 이해하기 더 어렵습니다.

In[69]:= Flatten[{{{1, 2, 3}, {4, 5}}, {{6, 7}, {8, 9, 10}}}, {{3}, {1}, {2}}] Out[69]= {{{1, 4}, {6, 8}}, {{2, 5}, {7, 9}}, {{3}, {10}}} 

다음 이미지는이 일반화 된 조옮김을 보여줍니다.

순환 일반화 된 전치 그림

2 개의 연속 단계로 수행 할 수 있습니다.

In[72]:= step1 = Flatten[{{{1,2,3},{4,5}},{{6,7},{8,9,10}}},{{1},{3},{2}}] Out[72]= {{{1,4},{2,5},{3}},{{6,8},{7,9},{10}}} In[73]:= step2 = Flatten[step1,{{2},{1},{3}}] Out[73]= {{{1,4},{6,8}},{{2,5},{7,9}},{{3},{10}}} 

순열 이후 {3,1,2}{1,3,2} 다음에 {2,1,3}로 가져올 수 있습니다. 작동 방식을 확인하는 또 다른 방법은 숫자 사용 wh ich는 목록 구조의 위치를 나타냅니다.

Flatten[{{{111, 112, 113}, {121, 122}}, {{211, 212}, {221, 222, 223}}}, {{3}, {1}, {2}}] (* ==> {{{111, 121}, {211, 221}}, {{112, 122}, {212, 222}}, {{113}, {223}}} *) 

이로부터 가장 바깥 쪽 목록 (첫 번째 수준), 세 번째 색인 ( 원본 목록의 세 번째 수준)이 증가하고 각 구성원 목록 (두 번째 수준)에서 첫 번째 요소가 요소 당 (원래 목록의 첫 번째 수준에 해당) 증가하고 마지막으로 가장 안쪽 (세 번째 수준) 목록에서 두 번째 색인이 증가합니다. , 원래 목록의 두 번째 수준에 해당합니다. 일반적으로 두 번째 요소로 전달 된 목록의 k 번째 요소가 {n} 인 경우 결과 목록 구조에서 k 번째 색인을 늘리는 것은

마지막으로 다음과 같이 여러 레벨을 결합하여 하위 레벨을 효과적으로 병합 할 수 있습니다.

In[74]:= Flatten[{{{1,2,3},{4,5}},{{6,7},{8,9,10}}},{{2},{1,3}}] Out[74]= {{1,2,3,6,7},{4,5,8,9,10}} 

댓글

  • 숫자가 중첩 된 목록의 원래 위치를 나타내는 경우 ‘ 이해하기가 더 쉽습니다. 예를 들어 3 자리 순열 예에서는 Flatten[{{{111, 112, 113}, {121, 122}}, {{211, 212}, {{221,222,223}}}, {{3},{1},{2}}}이고 결과는 {{{111, 121}, {211, 221}}, {{112, 122}, {212, 222}}, {{113}, {223}}}입니다.
  • @celtschk 감사합니다.하지만 확신이 서지 않습니다. 개인적으로 시각적으로 구별되는 숫자를 추적하고 새 구조에서 끝나는 위치를 확인하는 것이 더 쉽습니다. 하지만 제 답변에 이걸 추가해도됩니다. 저에게는 완벽합니다.
  • 그 점에서 우리의 이해 방식은 다를 것 같습니다. 실제로 내 방식을 다시 작성한 후에야 순환 순열을 완전히 이해했습니다 (하지만 나중에 수행 한 2 단계 분해없이 직접). 요점은 이렇게하면 각 목록을 따라 이동하면 어떤 인덱스가 변경되는지 즉시 확인할 수 있으며 원래 목록을 보지 않고도 목록 구조에서 번호가 유래 한 위치를 확인할 수 있다는 것입니다. 다시 말해서, (적어도 나에게는) 변화의 구조 를 더 직접적으로 보여줍니다.
  • @celtschk 네, 당신의 추론을 이해했습니다. 하지만 저에게있어서 요소 ‘ 인덱스를 보는 것보다 어떤 요소가 어떤 목록을 뛰어 넘는 지 이해하는 것이 더 쉬웠습니다. ‘ 나만 그런 것일 수도 있습니다. 저는 항상 대수보다는 기하학에 끌 렸습니다. 두 가지 모두 장점이 있다고 생각합니다.
  • @LeonidShifrin In[63]:= Flatten[{{1,2,3},{4,5},{6,7},{8,9,10}},{{2},{1}}] Out[63]= {{1,4,6,8},{2,5,7,9},{3,10}}의 경우, 원래 목록에서 레벨 1을 구성한 요소가 이제 결과에서 레벨 2. 저는 ‘ 잘 이해하지 못합니다. 입력과 출력은 동일한 수준 구조를 가지고 있으며 요소는 여전히 동일한 수준에 있습니다. 이것을 전체적으로 설명해 주시겠습니까?

Answer

Flatten에 대한 두 번째 목록 인수는 두 가지를 제공합니다. 목적. 첫째, 요소를 수집 할 때 인덱스가 반복되는 순서를 지정합니다. 둘째, 최종 결과에서 목록 병합을 설명합니다. 이러한 각 기능을 차례로 살펴 보겠습니다.

반복 순서

다음 매트릭스를 고려하십시오.

$m = Array[Subscript[m, Row[{##}]]&, {4, 3, 2}]; $m // MatrixForm 

행렬 결과

다음을 사용할 수 있습니다. 모든 요소를 반복하여 행렬의 복사본을 만드는 Table 표현식 :

$m === Table[$m[[i, j, k]], {i, 1, 4}, {j, 1, 3}, {k, 1, 2}] (* True *) 

이 ID 작업은 흥미롭지 않지만 반복 변수의 순서를 바꾸어 배열을 변환 할 수 있습니다. 예를 들어 ij를 바꿀 수 있습니다. 이는 레벨 1 및 레벨 2 인덱스와 해당 요소를 교체하는 것과 같습니다.

$r = Table[$m[[i, j, k]], {j, 1, 3}, {i, 1, 4}, {k, 1, 2}]; $r // MatrixForm 

행렬 결과

자세히 살펴보면 각 원본 요소 $m[[i, j, k]]가 결과 요소 $r[[j, i, k]]-처음 두 인덱스에는 꿀벌이 있습니다. n “swapped”.

Flatten를 사용하면이 Table 표현식에 상응하는 연산을 더 간결하게 표현할 수 있습니다.

$r === Flatten[$m, {{2}, {1}, {3}}] (* True *) 

Flatten 표현식의 두 번째 인수는 원하는 색인 순서를 명시 적으로 지정합니다. 색인 1, 2, 3은 다음과 같습니다. 인덱스 2, 1, 3이되도록 변경되었습니다. 배열의 각 차원에 대해 범위를 지정할 필요가 없다는 점에 유의하십시오. 이는 중요한 표기법상의 편의입니다.

다음 Flatten는 인덱스 순서에 대한 변경을 지정하지 않기 때문에 ID 연산입니다.

$m === Flatten[$m, {{1}, {2}, {3}}] (* True *) 

다음 표현식은 세 인덱스를 모두 다시 정렬합니다. 1, 2 , 3-> 3, 2, 1

Flatten[$m, {{3}, {2}, {1}}] // MatrixForm 

행렬 결과

다시 , 색인 [[i, j, k]]에서 발견 된 원래 요소가 이제 결과의 [[k, j, i]]에서 발견되는지 확인할 수 있습니다.

표현식의 경우 마지막에 지정된 것처럼 자연스러운 순서로 처리됩니다.

Flatten[$m, {{3}}] === Flatten[$m, {{3}, {1}, {2}}] (* True *) 

이 마지막 예는 추가로 축약 됨 :

Flatten[$m, {3}] === Flatten[$m, {{3}}] (* True *) 

빈 색인 목록은 ID 작업을 수행합니다.

$m === Flatten[$m, {}] === Flatten[$m, {1}] === Flatten[$m, {{1}, {2}, {3}}] (* True *) 

반복 순서와 인덱스 스와핑을 처리합니다. 이제 살펴 보겠습니다 …

목록 병합

이전 예의 하위 목록에 각 색인을 지정해야하는 이유가 궁금 할 수 있습니다. 그 이유는 색인 사양의 각 하위 목록이 결과에서 함께 병합 될 색인을 지정하기 때문입니다. 다음 식별 작업을 다시 고려하세요.

Flatten[$m, {{1}, {2}, {3}}] // MatrixForm 

행렬 결과

처음 두 개의 인덱스를 동일한 하위 목록으로 결합하면 어떻게 되나요? ?

Flatten[$m, {{1, 2}, {3}}] // MatrixForm 

행렬 결과

원래 결과가 4 x 3 그리드 쌍이지만 두 번째 결과는 단순한 쌍 목록입니다. 가장 깊은 구조 인 쌍은 그대로 두었습니다. 처음 두 레벨은 단일 레벨로 평평 해졌습니다. 소스의 세 번째 레벨에있는 쌍 행렬은 평평하지 않은 상태로 유지되었습니다.

대신 두 번째 두 인덱스를 결합 할 수 있습니다.

Flatten[$m, {{1}, {2, 3}}] // MatrixForm 

행렬 결과

이 결과에는 원래 행렬과 동일한 수의 행이 있습니다. 즉, 첫 번째 수준은 그대로 유지되었습니다. 그러나 각 결과 행에는 세 쌍의 해당 원래 행에서 가져온 6 개 요소의 단순 목록이 있습니다. 따라서 하위 두 수준이 병합되었습니다.

또한 세 가지 인덱스를 모두 결합하여 완전히 병합 된 결과를 얻을 수 있습니다.

Flatten[$m, {{1, 2, 3}}] 

행렬 결과

축약 할 수 있습니다.

Flatten[$m, {{1, 2, 3}}] === Flatten[$m, {1, 2, 3}] === Flatten[$m] (* True *) 

Flatten는 인덱스 스왑이 발생하지 않을 때 단축 표기법도 제공합니다.

$n = Array[n[##]&, {2, 2, 2, 2, 2}]; Flatten[$n, {{1}, {2}, {3}, {4}, {5}}] === Flatten[$n, 0] (* True *) Flatten[$n, {{1, 2}, {3}, {4}, {5}}] === Flatten[$n, 1] (* True *) Flatten[$n, {{1, 2, 3}, {4}, {5}}] === Flatten[$n, 2] (* True *) Flatten[$n, {{1, 2, 3, 4}, {5}}] === Flatten[$n, 3] (* True *) 

“Ragged”배열

지금까지 모든 예제는 다양한 차원의 행렬을 사용했습니다. FlattenTable 표현식의 약어 이상의 기능을 제공하는 매우 강력한 기능을 제공합니다. Flatten는 주어진 수준에서 하위 목록의 길이가 다른 경우를 우아하게 처리합니다. 누락 된 요소는 조용히 무시됩니다. 예를 들어 삼각형 배열을 뒤집을 수 있습니다.

$t = Array[# Range[#]&, {5}]; $t // TableForm (* 1 2 4 3 6 9 4 8 12 16 5 10 15 20 25 *) Flatten[$t, {{2}, {1}}] // TableForm (* 1 2 3 4 5 4 6 8 10 9 12 15 16 20 25 *) 

…또는 뒤집어서 평평하게 :

Flatten[$t, {{2, 1}}] (* {1,2,3,4,5,4,6,8,10,9,12,15,16,20,25} *) 

댓글

  • 환상적이고 철저한 설명입니다!
  • @ rm-rf 감사합니다. Flatten가 인덱스를 평탄화 (계약) 할 때 적용 할 함수를 허용하도록 일반화했다면 “의 훌륭한 시작이 될 것이라고 생각합니다. 캔의 텐서 대수 “.
  • 때로는 내부 수축을해야합니다. 이제 특정 수준에서 Map Flatten 대신 Flatten[$m, {{1}, {2, 3}}]를 사용하여 할 수 있다는 것을 알고 있습니다. Flatten가 부정적 인수를 수락하면 좋을 것입니다. 따라서이 사례는 Flatten[$m, -2]와 같이 작성할 수 있습니다.
  • 이 우수한 답변이 Leonid ‘보다 적은 표를 얻은 이유 : (.
  • @Tangshutao 내 프로필 에서 두 번째 FAQ를 참조하세요.

답변

WReach “s와 Leonid”s 답변에서 많은 것을 배웠고 작은 기여를하고 싶습니다.

Flatten의 목록 값 두 번째 인수의 주요 의도는 단순히 특정 수준의 목록을 평면화하는 것임을 강조합니다 (WReach가 List Flattening 섹션). Flatten를 비정형 Transpose로 사용하면 측면처럼 보입니다. -제 생각에는이 기본 디자인의 효과입니다.

예를 들어 어제이 목록을 변환해야했습니다.

lists = { {{{1, 0}, {1, 1}}, {{2, 0}, {2, 4}}, {{3, 0}}}, {{{1, 2}, {1, 3}}, {{2, Sqrt[2]}}, {{3, 4}}} (*, more lists... *) }; 

treeform1

이 항목으로 :

list2 = { {{1, 0}, {1, 1}, {2, 0}, {2, 4}, {3, 0}}, {{1, 2}, {1, 3}, {2, Sqrt[2]}, {3, 4}} (*, more lists... *) } 

treeform2

즉, 두 번째와 세 번째 목록 수준을 함께 분쇄해야했습니다.

저는

list2 = Flatten[lists, {{1}, {2, 3}}]; 

답변

오래된 질문이지만 lot . 오늘이게 어떻게 작동하는지 설명하려고했을 때 꽤 명확한 설명을 발견 했으므로 여기서 공유하면 더 많은 청중에게 도움이 될 것 같습니다.

색인이란 무엇을 의미합니까?

먼저 index 가 무엇인지 명확히하겠습니다. Mathematica에서 모든 표현식은 트리입니다. 예를 들어 보겠습니다. 목록 :

TreeForm@{{1,2},{3,4}} 

illus1

트리를 탐색하는 방법

간단합니다! 루트에서 시작하여 각 교차점에서 갈 길을 선택합니다. 예를 들어 2에 도달하려면 첫 번째 경로를 선택한 다음 두 번째 경로를 선택합니다. 이 표현식에서 2 요소의 인덱스 인 {1,2}로 작성하겠습니다.

Flatten를 이해하는 방법?

완전한 표현을 제공하지 않고 대신 모든 요소를 제공하고 그들의 색인, 어떻게 원래의 표현을 구성합니까? 예를 들어 여기에 다음과 같은 정보를 제공합니다.

{<|"index" -> {1, 1}, "value" -> 1|>, <|"index" -> {1, 2}, "value" -> 2|>, <|"index" -> {2, 1}, "value" -> 3|>, <|"index" -> {2, 2}, "value" -> 4|>} 

그리고 모든 헤드가 List라고 말하면 원래 표현식?

음, 원래 표현식을 {{1,2},{3,4}}로 재구성 할 수 있지만 방법은 다음과 같습니다. 다음 단계를 나열 할 수 있습니다.

  1. 먼저 색인의 첫 번째 요소를 살펴보고이를 기준으로 정렬 및 수집합니다. 그런 다음 첫 번째 전체 표현식의 요소는 원래 목록의 처음 두 개 요소를 포함해야합니다 …
  2. 그런 다음 두 번째 인수를 계속 살펴보고 동일한 작업을 수행합니다 …
  3. 마지막으로 원래 목록은 {{1,2},{3,4}}입니다.

그게 합리적입니다! 그렇다면, 아니오라고 말하면 먼저 색인의 두 번째 요소를 기준으로 정렬하고 수집 한 다음 색인의 첫 번째 요소를 기준으로 수집해야합니까? 아니면 두 번 모으지 않고 두 요소를 기준으로 정렬하고 첫 번째 인수에 더 높은 우선 순위를 부여한다고하나요?

음, 아마도 다음 두 목록을 각각 얻을 수 있겠죠?

  1. {{1,3},{2,4}}
  2. {1,2,3,4}

음, 직접 확인해보세요. Flatten[{{1,2},{3,4}},{{2},{1}}]Flatten[{{1,2},{3,4}},{{1,2}}]도 똑같이합니다!

플랫 튼의 두 번째 인수를 이해하는 방법 ?

  1. 기본 목록 내의 각 목록 요소 (예 : {1,2})는 색인의 이러한 요소에 따라 모든 목록, 즉 이러한 수준 .
  2. 목록 요소 내부의 순서는 이전 단계에서 목록 내부에 수집 된 요소를 SORT 방식을 나타냅니다. . 예를 들어 {2,1}는 두 번째 수준의 위치가 첫 번째 수준의 위치보다 우선 순위가 더 높다는 것을 의미합니다.

이제 이전 규칙에 익숙해 지도록 연습 해 보겠습니다.

1. Transpose

는 $ A_ {i, j} \ rightarrow A ^ T_ {j, i} $를 만드는 것입니다. 그러나 다른 방법으로 고려할 수 있습니다. 원래는 요소를 i 색인별로 먼저 정렬 한 다음 j 색인별로 정렬합니다. 이제 j 먼저 색인을 생성 한 다음 i별로 색인을 생성합니다. 따라서 코드는 다음과 같습니다.

Flatten[mat,{{2},{1}}] 

간단하지 않습니까?

2. 전통적인 Flatten

간단한 m * n 행렬에서 전통적인 병합의 목표는 2D 행렬 대신 1D 배열을 만듭니다. 예 : Flatten[{{1,2},{3,4}}]{1,2,3,4}. 즉, 이번에는 요소를 수집 하지 않고 첫 번째 색인을 기준으로 한 다음 두 번째 색인을 기준으로 정렬합니다.

Flatten[mat,{{1,2}}] 

3. ArrayFlatten

가장 간단한 ArrayFlatten 사례에 대해 논의하겠습니다. 여기에 4D 목록이 있습니다.

{{{{1,2},{5,6}},{{3,4},{7,8}}},{{{9,10},{13,14}},{{11,12},{15,16}}}} 

그러면 어떻게 2D 목록으로 만들기 위해 이러한 변환을 수행 할 수 있습니까?

$ \ left (\ begin {array} {cc} \ left (\ begin {array} {cc} 1 & 2 \\ 5 & 6 \\ \ end {array} \ right) & \ 왼쪽 (\ begin {array} {cc} 3 & 4 \\ 7 & 8 \\ \ end {array} \ right) \\ \ left (\ begin {array} {cc} 9 & 10 \\ 13 & 14 \\ \ end {array} \ right) & \ left (\ begin {array} {cc} 11 & 12 \\ 15 & 16 \\ \ end {array} \ right) \\ \ end {array} \ right) \ rightarrow \ left (\ begin {array} {cccc} 1 & 2 & 3 & 4 \\ 5 & 6 & 7 & 8 \\ 9 & 10 & 11 & 12 \\ 13 & 14 & 15 & 16 \\ \ end {array} \ right) $

음, 이것도 간단합니다. 먼저 원래의 첫 번째 및 세 번째 수준 색인에 의한 그룹이 필요하고 첫 번째 색인에 더 높은 우선 순위를 부여해야합니다. 정렬. 두 번째 및 네 번째 수준도 마찬가지입니다.

Flatten[mat,{{1,3},{2,4}}] 

4. 이미지 “크기 조정”

이제 이미지가 생겼습니다. 예를 들면 다음과 같습니다.

img=Image@RandomReal[1,{10,10}] 

하지만 확실히 너무 작아서 따라서 각 픽셀을 10 * 10 크기의 거대한 픽셀로 확장하여 더 크게 만들고 싶습니다.

먼저 시도해 보겠습니다.

ConstantArray[ImageData@img,{10,10}] 

하지만 {10,10,10,10} 차원의 4D 행렬을 반환합니다. 따라서 Flatten를 사용해야합니다. 이번에는 대신 세 번째 인수가 더 높은 우선 순위를 갖기를 원합니다. 따라서 약간의 조정이 가능합니다.

Image@Flatten[ConstantArray[ImageData@img,{10,10}],{{3,1},{4,2}}] 

비교 :

illus2

도움이되기를 바랍니다.

답글 남기기

이메일 주소를 발행하지 않을 것입니다. 필수 항목은 *(으)로 표시합니다