줄리아에서 배열의 원소들이 어떤 리스트에 속하는지 체크하는 법

줄리아에서 배열의 원소들이 어떤 리스트에 속하는지 체크하는 법

How to Check that Elements in Array are in some List

가이드 1

julia> x = rand('a':'c', 10)
10-element Vector{Char}:
 'a': ASCII/Unicode U+0061 (category Ll: Letter, lowercase)
 'a': ASCII/Unicode U+0061 (category Ll: Letter, lowercase)
 'b': ASCII/Unicode U+0062 (category Ll: Letter, lowercase)
 'c': ASCII/Unicode U+0063 (category Ll: Letter, lowercase)
 'b': ASCII/Unicode U+0062 (category Ll: Letter, lowercase)
 'c': ASCII/Unicode U+0063 (category Ll: Letter, lowercase)
 'c': ASCII/Unicode U+0063 (category Ll: Letter, lowercase)
 'c': ASCII/Unicode U+0063 (category Ll: Letter, lowercase)
 'b': ASCII/Unicode U+0062 (category Ll: Letter, lowercase)
 'b': ASCII/Unicode U+0062 (category Ll: Letter, lowercase)

위와 같은 배열이 있다고 하자. 예제에서 우리의 목표는 'a''b' 를 모두 골라내는 것이라고 하자. 상식적으로는 포함기호 $\in$로 브로드캐스트하면 될 것 같지만, 결과는 다음과 같다.

julia> x .∈ ['a', 'b']
ERROR: DimensionMismatch("arrays could not be broadcast to a common size; got a dimension with lengths 10 and 2")

DimensionMismatch 에러가 레이즈되었다. 이는 브로드캐스팅이 배열 x 와 범주 ['a', 'b'] 양쪽에 동시에 일어났기 때문에 발생한 에러다. 에러메세지를 해석해보자면 x 의 길이 10과 ['a', 'b']의 길이 2가 동시에 들어와서 혼란스럽다는 것이다.

julia> x .∈ Ref(['a', 'b'])
10-element BitVector:
 1
 1
 1
 0
 1
 0
 0
 0
 1
 1

이럴떈 Ref() 함수를 통해 브로드캐스팅 문제를 해결할 수 있다. 이를 통해 ['a', 'b'] 속의 'a''b' 가 스칼라로 취급되고, 위와 같이 두 개의 캐릭터가 있는 곳만을 찾아낼 수 있었다.

주의사항

julia> y = rand('a':'c', 1, 10)
1×10 Matrix{Char}:
 'b'  'a'  'b'  'b'  'a'  'c'  'a'  'b'  'b'  'c'

위와 같이 $1 \times 10$ 행렬인 경우를 생각해보자. 언뜻보면 위 가이드에서 본 경우와 다를 게 없어야 할 것 같지만, .∈ 가 전혀 다른 방식으로 사용된다.

julia> y .∈ ['a', 'b']
2×10 BitMatrix:
 0  1  0  0  1  0  1  0  0  0
 1  0  1  1  0  0  0  1  1  0

보다시피 첫 행은 'a' 의 위치를, 둘째 행은 'b' 의 위치를 나타내주고 있다. 이는 벡터냐 행렬이냐의 차이에서 온 것이다.

julia> y .∈ Ref(['a', 'b'])
1×10 BitMatrix:
 1  1  1  1  1  0  1  1  1  0

Ref() 를 사용하는 경우에는 일관된 결과를 얻을 수 있다.

환경

  • OS: Windows
  • julia: v1.7.0

  1. https://stackoverflow.com/a/59978386/12285249 ↩︎

댓글