데이터셋을 다루는데 데이터셋의 라벨링이 numpy void로 되어있고 그 데이터가 도대체 어떤 형태로 정리가 되어있는건지 이해할 수 없어서 numpy void 에 대해서 공부해보았다.
이 글에서는 개념적인 내용보다는 numpy void 로 정리된 데이터를 어떻게 이해할 수 있으며 어떻게 사용하는지에 대해서만 간략한 예시로만 정리하겠다.
dataset.labels['table'][sample_idx]
(0, 1690, 1, [[[1357., 1759.], [1240., 1544.], [1137., 1681.], [1234., 1659.],
[1320., 1534.], [1403., 1748.], [1169., 1646.], [1091., 1637.], [1079., 1538.],
[1186., 1509.], [1305., 1590.], [1373., 1613.], [1127., 1495.], [1117., 1384.],
[1185., 1670.], [1135., 1597.], [1130., 1460.]], [[1107., 1240.], [1004., 1144.],
[ 916., 1250.], [ 950., 1225.], [1032., 1129.], [1121., 1229.], [ 979., 1214.],
[ 906., 1227.], [ 847., 1175.], [ 894., 1141.], [ 986., 1171.], [1050., 1170.],
...
...
...
[0.000000e+00, 0.000000e+00, 1.000000e+00]]])
특정 index에는 무슨 값이 있는지 궁금해서 dataset.labels['table'][sample_idx] 를 출력해보니 위 처럼 어마어마하게 많은 데이터가 출력되는 상황이었다.
dataset.labels['table'][sample_idx].shape
()
그런데 웃기게도 shape을 확인해보니 빈 공란이 나오지 않나?
type(dataset.labels['table'][sample_idx])
<class 'numpy.void'>
그래서 type을 확인해보니 numpy.void 가 나온다. 드디어 문제의 데이터가 나왔다..
결론부터 말하자면 numpy.void 는 C언어의 구조체와 비슷한 개념으로 보인다. C언어 구조체는 사용자가 임의로 데이터타입을 지정하는 자료형이고, 그 안에는 1개 이상의 데이터를 사용자가 지정하는대로 넣을 수 있다. numpy.void 도 마찬가지더라.
따라서 구조체나 파이썬 딕셔너리처럼 데이터의 이름으로 어떻게하면 접근할 수 있는가했더니 아래처럼 하면 되더라.
dataset.labels['table'][sample_idx].dtype
dtype([('subject_idx', 'i1'), ('frame_idx', '<i2'), ('sequence_idx', '<i2'),
('keypoints_2d', '<f4', (8, 17, 2)), ('keypoints', '<f4', (17, 3)),
('bbox_by_camera_tlbr', '<i2', (8, 4)), ('R', '<f4', (8, 3, 3)),
('t', '<f4', (8, 3, 1)), ('K', '<f4', (8, 3, 3))])
void 형태의 데이터를 만들기 위해서는 먼저 dtype부터 설정해야 numpy.void 의 데이터를 만들 수 있는데, 이는 바로 위 코드처럼 확인할 수 있다. 이 글에서는 왜 dtype 부터 설정해야하고, numpy.void 형태의 데이터를 만드는 방법에 대해서는 다루지 않겠다.
결론적으로 void형태의 데이터에 접근하기 위해서 dtype을 확인했으니 이제 다음처럼 접근하면 된다.
dataset.labels['table'][sample_idx]['keypoints_2d']
array([[[1357., 1759.],
[1240., 1544.],
[1137., 1681.],
[1234., 1659.],
[1320., 1534.],
[1403., 1748.],
[1169., 1646.],
[1091., 1637.],
[1079., 1538.],
[1186., 1509.],
[1305., 1590.],
[1373., 1613.],
[1127., 1495.],
[1117., 1384.],
[1185., 1670.],
[1135., 1597.],
[1130., 1460.]],
...
...
...
[[ 340., 1311.],
[ 527., 1175.],
[ 694., 1352.],
[ 690., 1408.],
[ 511., 1211.],
[ 325., 1333.],
[ 543., 1236.],
[ 665., 1261.],
[ 809., 1241.],
[ 812., 1278.],
[ 654., 1366.],
[ 507., 1341.],
[ 825., 1230.],
[ 853., 1107.],
[ 692., 1380.],
[ 799., 1336.],
[ 820., 1189.]]], dtype=float32)
void 안에 subject_idx, frame_idx, sequence_idx, keypoints_2d, keypoints, bbox_by_camera_tlbr, R, t, K 라는 이름의 데이터들이 있다는것을 .dtype을 통해 확인했기 때문이다.
numpy.void의 개념에 대해서 좀 더 자세히 정리해둔 글의 링크를 첨부한다.
https://cumulu-s.tistory.com/14