본문 바로가기
Python/NumPy

Record array(레코드 배열)에서의 Recarray Helper Functions - NumPy(12)

by 콩돌 2019. 2. 26.
반응형

참고 자료

https://docs.scipy.org/doc/numpy/user/basics.rec.html



파이썬 버전 3.7 기준

NumPy 버전 1.16 기준


본 포스팅에서는 NumPy에서의 Structured Array의 Record array를 다루기 위한 유용한 함수(Recarray Helper Function)에 대해 포스팅한다.



Structured array(구조체 배열)의 Record array(레코드 배열)에서의 유용한 함수


Recarray Helper Functions
Recarray Helper Function은 구조체 배열을조작하기 위한 유틸리티를 모아놓은 것이다.
이 함수들의 대부분은 John Hunter가 matplotlib용으로 처음 구현하였고, 편의를 위해 재작성되고 확장시켰다.

numpy.lib.recfunctions.append_fields(base, names, data, dtypes=None, fill_value=-1, usemask=True, asrecarray=False)
  ○ 이 함수는 base에 입력되는 배열을 확장시켜준다.
  ○ 확장시 입력되는 구조체는 data이며 names라는 필드 이름을 가진다.
  ○ 각 입력변수에 대한 설명은 다음 표와 같다.

 입력 변수

 입력 단위

 설명

 base

 array

 확장시키기 위한 배열을 입력받는다.

 names

 string, sequence

 base에 추가할 배열의 필드 이름을 입력하며, 문자열이나 문자열의 시퀀스(리스트 등)를 입력받는다.

 data

 array, sequence of array

 base에 추가할 배열의 데이터를 입력하기 위해 배열이나 배열의 시퀀스(리스트 등)를 입력받는다.

 dtypes

 sequence of datatype

 추가할 배열의 자료형에 대한 시퀀스를 입력받는다. (선택적으로 사용 가능)

 fill_value

 float

 데이터가 빈 경우에 fill_value에 입력된 값을 사용하여 채운다. (선택적으로 사용 가능)

 usemask

 {True, False}

 마스크 배열을 반환 여부를 결정하는 변수이다. (선택적으로 사용 가능)

 asrecarray

 {True, False}

 recarray를 반환할 것인지 아닌지 여부를 결정하는 변수이다. (선택적으로 사용 가능)



numpy.lib.recfunctions.drop_fields(base, drop_names, usemask=True, asrecarray=False)
  ○ drop_names에 입력되는 필드를 제거한 새로운 배열을 반환한다. 
  ○ 중첩된 필드를 지원한다.
  ○ 각 입력변수에 대한 설명은 다음 표와 같다.

 입력 변수

 입력 단위

 설명

 base

 array

 제거를 수행할 배열을 입력받는다.

 drop_names

 string, sequence

 base에서 제거할 배열의 필드 이름을 입력하며, 문자열이나 문자열의 시퀀스(리스트 등)를 입력받는다.

 usemask

 {True, False}

 마스크 배열을 반환 여부를 결정하는 변수이다. (선택적으로 사용 가능)

 asrecarray

 {True, False}

 recarray를 반환할 것인지 아닌지 여부를 결정하는 변수이다. (선택적으로 사용 가능)


사용 예)
# import recfunctions 반드시 해야 함
In[11]: from numpy.lib import recfunctions as rf

# 예제용 입력
In[12]: x = np.array([(1, (1, 1)), (2, (2, 2))], dtype=[('a', int), ('b', [('c', float), ('d', int)])])

# drop_fields를 이용한 필드 제거
In[13]: rf.drop_fields(x,'a')
Out[13]: 
array([((1., 1),), ((2., 2),)],
      dtype=[('b', [('c', '<f8'), ('d', '<i4')])])
In[14]: rf.drop_fields(x,'d')
Out[14]: 
array([(1, (1.,)), (2, (2.,))],
      dtype=[('a', '<i4'), ('b', [('c', '<f8')])])
In[15]: rf.drop_fields(x,'b')
Out[15]: array([(1,), (2,)], dtype=[('a', '<i4')])

※ 주의 : numpy.lib.recfunctions.사용할함수 와 같은 형식으로 접근을 하고자하면 예외가 발생하므로 from numpy.lib import recfunctions as ~ 의 형태로 불러와 준후 사용하는 것을 권장한다.

numpy.lib.recfunctions.find_duplicates(a, key=None, ignoremask=True, return_index=False)
  ○ 주어진 key를 따라 구조체 배열속에서 복사본을 찾는다.
  ○ 각 입력변수에 대한 설명은 다음 표와 같다.

 입력 변수

 입력 단위

 설명

 a

 array-like

 해당 함수의 기능을 수행할 배열을 입력받는다.

 key

 string, sequence

 중복여부를 확인 할 필드의 이름을 입력받는다, 만약에 없다면, 레코드에 의해 검색이 수행된다(선택적으로 사용 가능)

 ignoremask

 {True, False}

 마스크 데이터가 제거될 것인지 중복된 것으로 고려될 것인지 결정하는 변수이다. (선택적으로 사용 가능)

 return_index

 {True, False}

 중복된 값들의 인덱스에 대한 반환 여부를 결정하는 변수이다. (선택적으로 사용 가능)



사용 예)
# import recfunctions 반드시 해야 함
In[17]: from numpy.lib import recfunctions as rf

# 예제용 입력
In[18]: x = np.ma.array([1, 1, 1, 2, 2, 3, 3], mask=[0,0,1,0,0,0,1]).view([('a', int)])

#함수 출력결과물들
In[19]: rf.find_duplicates(x, ignoremask=True, return_index=False)
Out[19]: 
masked_array(data=[(1,), (1,), (2,), (2,)],
             mask=[(False,), (False,), (False,), (False,)],
       fill_value=(999999,),
            dtype=[('a', '<i4')])

In[20]: rf.find_duplicates(x, ignoremask=True, return_index=True)
Out[20]: 
(masked_array(data=[(1,), (1,), (2,), (2,)],
              mask=[(False,), (False,), (False,), (False,)],
        fill_value=(999999,),
             dtype=[('a', '<i4')]), array([0, 1, 3, 4], dtype=int32))


numpy.lib.recfunctions.get_fieldstructure(adtype, lastname=None, parents=None)
  ○ 각 필드가 가지는 상위 필드를 리스트로 반환한다.
  ○ 각 입력변수에 대한 설명은 다음 표와 같다.

 입력 변수

 입력 단위

 설명

 adtype

 array-like

 해당 함수의 기능을 수행할 배열을 입력받는다.

 lastname

 -

 마지막으로 진행된 필드 이름을 입력받는다. (선택적으로 사용 가능, 재귀중 내부적으로 사용한다.)

 parents

 -

 상위 필드의 딕셔너리를 입력받는다. (선택적으로 사용 가능, 재귀중 내부적으로 사용한다.)


사용 예)
# import recfunctions 반드시 해야 함
In[21]: from numpy.lib import recfunctions as rf

# 함수 실행 결과
In[22]: ntype= np.dtype([('a',int),
                 ('b',[('ba', int), ('bb', [('bba',int), 
                                            ('bbb',int)])])])
In[23]: rf.get_fieldstructure(ntype)
Out[23]: 
{'a': [],
 'b': [],
 'ba': ['b'],
 'bb': ['b'],
 'bba': ['b', 'bb'],
 'bbb': ['b', 'bb']}

numpy.lib.recfunctions.join_by(key, r1, r2, jointype='inner', r1postfix='1', r2postfix='2', defaults=None, usemask=True, asrecarray=False)
  ○ key에 입력된 필드에서 배열 r1과 r2를 조인시킨다.

  ○ key는 반드시 문자열이거나 문자열의 시퀀스로 구성되어야 한다. 
    ▷ 각 필드에 해당하는 문자열이어야 한다.
    ▷ 만약 key 필드를 배열 r1과 r2에서 찾을 수가 없다면 예외가 발생한다. 
  ○ 배열 r1이나 r2가 키에 따라 중복되는 필드를 가지고 있으면 안된다. 
    ▷ 중복되는 필드가 존재할 경우 출력의 신뢰성이 떨어진다.
    ▷ 중복되는 필드는 알고리즘에 의해 찾아질 수 없다.
  ○ 각 입력변수에 대한 설명은 다음 표와 같다.

 입력 변수

 입력 단위

 설명

 key

 {string, sequence}

 비교에 사용된 필드에 해당하는 문자열 또는 문자열 시퀀스를 입력받는다.

 r1, r2

 array

 입력되는 구조체 배열이다.

 jointype

 {'inner','outer','leftouter}

 - inner일 경우 r1과 r2의 공통되는 요소를 반환한다. (교집합)

 - outer일 경우 r1와 r2의 공통되는 요소와 그렇지 않은 요소를 반환한다.(합집합)

 - leftouter일 경우 공통 요소와 r2에 있지 않은 r1의 요소를 반환한다.

 - 이 변수는 선택적으로 사용 가능한 독립변수이며 기본값은 inner이다.

 r1postfix

 string

 key에는 없지만 r2필드에 있으면서 r1 필드의 이름에 추가될 문자열을 입력받는다. (선택적으로 사용 가능)

 r2postfix

 string

 key에는 없지만 r1필드에 있으면서 r2 필드의 이름에 추가될 문자열을 입력받는다. (선택적으로 사용 가능)

 defaults

 {dictionary}

 해당 기본값으로 필드 이름을 매핑하는 딕셔너리 입력이다. (선택적으로 사용 가능)

 usemask

 {True, False}

 마스크 배열을 반환 여부를 결정하는 변수이다. (선택적으로 사용 가능)

 asrecarray

 {True, False}

 recarray를 반환할 것인지 아닌지 여부를 결정하는 변수이다. (선택적으로 사용 가능)


numpy.lib.recfunctions.merge_arrays(seqarrays, fill_value=-1, flatten=False, usemask=False, asrecarray=False)
  ○ 배열을 필드대 필드로 합친다. 
  ○ 각 입력변수에 대한 설명은 다음 표와 같다.

 입력 변수

 입력 단위

 설명

 seqarrays

 sequence of ndarrays

 배열의 시퀀스를 입력으로 받는다.

 fill_value

 {float}

 데이터가 빈 경우에 fill_value에 입력된 값을 사용하여 채운다. (선택적으로 사용 가능)

 flatten

 {True, False}

 중첩된 필드를 제거할 것인지 여부를 결정한다. (선택적으로 사용 가능)

 usemask

 {True, False}

 마스크 배열을 반환 여부를 결정하는 변수이다. (선택적으로 사용 가능)

 asrecarray

 {True, False}

 recarray를 반환할 것인지 아닌지 여부를 결정하는 변수이다. (선택적으로 사용 가능)


사용 예)
# import recfunctions 반드시 해야 함
In[27]: from numpy.lib import recfunctions as rf

# 함수 입력 및 결과 
In[28]: rf.merge_arrays((np.array([1,1]), np.array([2.,2.,2.])))
Out[28]: array([( 1, 2.), ( 1, 2.), (-1, 2.)], dtype=[('f0', '<i4'), ('f1', '<f8')])

In[29]: rf.merge_arrays((np.array([1,1]), np.array([100.,50.,30.])), usemask=False, asrecarray=True)
Out[29]: 
rec.array([( 1, 100.), ( 1,  50.), (-1,  30.)],
          dtype=[('f0', '<i4'), ('f1', '<f8')])


numpy.lib.recfunctions.rec_append_fields(base, names, data, dtypes=None)
  ○ 현재 존재하는 배열에 새로운 필드를 추가시킨다. 
    ▷ np.recarray가 결과로 반환된다.
  ○ 필드의 이름은 names독립변수에 주어지며, 각 필드에 해당하는 값은 data에 입력된다.
  ○ 만약 하나의 필드가 더해진다면 names와 data, dtype은 리스트여서는 안되고 값을 입력해야한다. 
  ○ 각 입력변수에 대한 설명은 다음 표와 같다.

 입력 변수

 입력 단위

 설명

 base

 array

 확장시키기 위한 배열을 입력받는다.

 names

 string, sequence

 base에 추가할 배열의 필드 이름을 입력하며, 문자열이나 문자열의 시퀀스(리스트 등)를 입력받는다.

 data

 array, sequence of array

 base에 추가할 배열의 데이터를 입력하기 위해 배열이나 배열의 시퀀스(리스트 등)를 입력받는다.

 dtypes

 sequence of datatype

 추가할 배열의 자료형에 대한 시퀀스를 입력받는다. (선택적으로 사용 가능)

 fill_value

 float

 데이터가 빈 경우에 fill_value에 입력된 값을 사용하여 채운다. (선택적으로 사용 가능)

 usemask

 {True, False}

 마스크 배열을 반환 여부를 결정하는 변수이다. (선택적으로 사용 가능)

 asrecarray

 {True, False}

 recarray를 반환할 것인지 아닌지 여부를 결정하는 변수이다. (선택적으로 사용 가능)


numpy.lib.recfunctions.rec_drop_fields(base, drop_names)
  ○ drop_names에 입력된 필드가 제거된 새로운 numpy.recarray를 반환한다.
  ○ 각 입력변수에 대한 설명은 다음 표와 같다.

 입력 변수

 입력 단위

 설명

 base

 array

 제거를 수행할 배열을 입력받는다.

 drop_names

 string, sequence

 base에서 제거할 배열의 필드 이름을 입력하며, 문자열이나 문자열의 시퀀스(리스트 등)를 입력받는다.


numpy.lib.recfunctions.rec_join(key, r1, r2, jointype='inner', r1postfix='1', r2postfix='2', defaults=None)
  ○ key에 입력된 필드에서 배열 r1과 r2를 조인시키며, 항상 np.recarray를 반환한다.
  ○ 각 입력변수에 대한 설명은 다음 표와 같다.

 입력 변수

 입력 단위

 설명

 key

 {string, sequence}

 비교에 사용된 필드에 해당하는 문자열 또는 문자열 시퀀스를 입력받는다.

 r1, r2

 array

 입력되는 구조체 배열이다.

 jointype

 {'inner','outer','leftouter}

 - inner일 경우 r1과 r2의 공통되는 요소를 반환한다. (교집합)

 - outer일 경우 r1와 r2의 공통되는 요소와 그렇지 않은 요소를 반환한다.(합집합)

 - leftouter일 경우 공통 요소와 r2에 있지 않은 r1의 요소를 반환한다.

 - 이 변수는 선택적으로 사용 가능한 독립변수이며 기본값은 inner이다.

 r1postfix

 string

 key에는 없지만 r2필드에 있으면서 r1 필드의 이름에 추가될 문자열을 입력받는다. (선택적으로 사용 가능)

 r2postfix

 string

 key에는 없지만 r1필드에 있으면서 r2 필드의 이름에 추가될 문자열을 입력받는다. (선택적으로 사용 가능)

 defaults

 {dictionary}

 해당 기본값으로 필드 이름을 매핑하는 딕셔너리 입력이다. (선택적으로 사용 가능)


numpy.lib.recfunctions.recursive_fill_fields(input, output)
  ○ 중첩된 구조체를 지원하여 입력 필드를 출력 필드에 채운다.

 입력 변수

 입력 단위

 설명

 input

 ndarray

 입력되는 배열이다.

 output

 ndarray

 출력되는 배열이다.


사용 예)

# import recfunctions 반드시 해야 함

In[35]: from numpy.lib import recfunctions as rf


# 예제용 입력

In[36]: x = np.array([(1,1), (2,2)], dtype=[('a', int), ('b', float)])

In[37]: y = np.zeros((3,), dtype=x.dtype)


# 함수 실행 결과

In[38]:rf.recursive_fill_fields(x,y)

Out[38]: array([(1, 1.), (2, 2.), (0, 0.)], dtype=[('a', '<i4'), ('b', '<f8')])





numpy.lib.recfunctions.rename_fields(base, namemapper)
  ○ ndarray나 recarray에서의 필드의 이름을 재설정한다. 
  ○ 중첩된 필드에도 지원된다. 

 입력 변수

 입력 단위

 설명

 base

 array

 필드가 수정되어야할 배열을 입력받는다.

 namemapper

 dictionary

 오래된 필드 이름을 새버전으로 매핑하고자하는 딕셔너리를 입력받는다.


사용 예)

# import recfunctions 반드시 해야 함

In[32]: from numpy.lib import recfunctions as rf

# 예제용 입력

In[33]: x = np.array([(1,(1,[1,1])), (2,(2,[2,2]))], dtype=[('a', int), ('b', [('ba',float), ('bb', (float,2))])])


# 함수 적용 결과

In[34]: rf.rename_fields(x,{'a':'X01', 'b':'X02', 'bb':'bbq'})

Out[34]: 

array([(1, (1., [1., 1.])), (2, (2., [2., 2.]))],

      dtype=[('X01', '<i4'), ('X02', [('ba', '<f8'), ('bbq', '<f8', (2,))])])




numpy.lib.recfunctions.stack_arrays(arrays, defaults=None, usemask=True, asrecarray=False, autoconvert=False)
  ○ 필드를 기준으로 배열을 필드로 중첩시킨다. 

 입력 변수

 입력 단위

 설명

 arrays

 sequence of input arrays

 배열의 시퀀스를 입력받는다.

 default

 dictionary

 해당 기본값으로 필드 이름을 매핑하는 딕셔너리 입력이다. (선택적으로 사용 가능)

 usemask

 {True, False}

 마스크 배열을 반환 여부를 결정하는 변수이다. (선택적으로 사용 가능)

 asrecarray

 {False, True}

 recarray를 반환할 것인지 아닌지 여부를 결정하는 변수이다. (선택적으로 사용 가능)

 autoconvert

 {False, True}

 필드 타입을 최대로 자동 캐스팅 할지 여부를 결정하는 변수이다. (선택적으로 사용 가능)


사용 예)

# import recfunctions 반드시 해야 함

In[41]: from numpy.lib import recfunctions as rf


#  하나의 배열만 입력했을 경우

In[42]: x = np.array([1,1,1])

In[43]: rf.stack_arrays(x) is x

Out[43]: True


#  두 배열을 입력했을 경우

In[44]: y = np.array([('a',1), ('b',2)], dtype=[('a', '|S3'), ('b', float)])

In[45]: z = np.array([('a',10, 100), ('b',20,200)], dtype=[('a', '|S3'), ('b', float), ('c',float)])

In[46]: stack_yz = rf.stack_arrays((y,z))

In[47]: stack_yz

Out[47]: 

masked_array(data=[(b'a', 1.0, --), (b'b', 2.0, --), (b'a', 10.0, 100.0),

                   (b'b', 20.0, 200.0)],

             mask=[(False, False,  True), (False, False,  True),

                   (False, False, False), (False, False, False)],

       fill_value=(b'N/A', 1.e+20, 1.e+20),

            dtype=[('a', 'S3'), ('b', '<f8'), ('c', '<f8')])



반응형

댓글