내 머리를 감쌀 수 없었던 한 가지는 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}}
댓글
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 작업은 흥미롭지 않지만 반복 변수의 순서를 바꾸어 배열을 변환 할 수 있습니다. 예를 들어 i
및 j
를 바꿀 수 있습니다. 이는 레벨 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”배열
지금까지 모든 예제는 다양한 차원의 행렬을 사용했습니다. Flatten
는 Table
표현식의 약어 이상의 기능을 제공하는 매우 강력한 기능을 제공합니다. 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... *) };
이 항목으로 :
list2 = { {{1, 0}, {1, 1}, {2, 0}, {2, 4}, {3, 0}}, {{1, 2}, {1, 3}, {2, Sqrt[2]}, {3, 4}} (*, more lists... *) }
즉, 두 번째와 세 번째 목록 수준을 함께 분쇄해야했습니다.
저는
list2 = Flatten[lists, {{1}, {2, 3}}];
답변
오래된 질문이지만 lot . 오늘이게 어떻게 작동하는지 설명하려고했을 때 꽤 명확한 설명을 발견 했으므로 여기서 공유하면 더 많은 청중에게 도움이 될 것 같습니다.
색인이란 무엇을 의미합니까?
먼저 index 가 무엇인지 명확히하겠습니다. Mathematica에서 모든 표현식은 트리입니다. 예를 들어 보겠습니다. 목록 :
TreeForm@{{1,2},{3,4}}
트리를 탐색하는 방법
간단합니다! 루트에서 시작하여 각 교차점에서 갈 길을 선택합니다. 예를 들어 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,4}}
입니다.
그게 합리적입니다! 그렇다면, 아니오라고 말하면 먼저 색인의 두 번째 요소를 기준으로 정렬하고 수집 한 다음 색인의 첫 번째 요소를 기준으로 수집해야합니까? 아니면 두 번 모으지 않고 두 요소를 기준으로 정렬하고 첫 번째 인수에 더 높은 우선 순위를 부여한다고하나요?
음, 아마도 다음 두 목록을 각각 얻을 수 있겠죠?
-
{{1,3},{2,4}}
-
{1,2,3,4}
음, 직접 확인해보세요. Flatten[{{1,2},{3,4}},{{2},{1}}]
와 Flatten[{{1,2},{3,4}},{{1,2}}]
도 똑같이합니다!
플랫 튼의 두 번째 인수를 이해하는 방법 ?
- 기본 목록 내의 각 목록 요소 (예 :
{1,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}}]
비교 :
도움이되기를 바랍니다.
Flatten[{{{111, 112, 113}, {121, 122}}, {{211, 212}, {{221,222,223}}}, {{3},{1},{2}}}
이고 결과는{{{111, 121}, {211, 221}}, {{112, 122}, {212, 222}}, {{113}, {223}}}
입니다.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. 저는 ‘ 잘 이해하지 못합니다. 입력과 출력은 동일한 수준 구조를 가지고 있으며 요소는 여전히 동일한 수준에 있습니다. 이것을 전체적으로 설명해 주시겠습니까?