일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | |||
5 | 6 | 7 | 8 | 9 | 10 | 11 |
12 | 13 | 14 | 15 | 16 | 17 | 18 |
19 | 20 | 21 | 22 | 23 | 24 | 25 |
26 | 27 | 28 | 29 | 30 | 31 |
Tags
- 도커
- Pull Request
- vscode
- AIFFEL
- 백신후원
- IVI
- cocre
- docker
- 프로그래머스
- airflow
- 티스토리챌린지
- WSSS
- logistic regression
- CellPin
- 오블완
- docker attach
- aiffel exploration
- ssh
- Decision Boundary
- Jupyter notebook
- HookNet
- 히비스서커스
- Multi-Resolution Networks for Semantic Segmentation in Whole Slide Images
- 사회조사분석사2급
- GIT
- numpy
- docker exec
- cs231n
- 코크리
- 기초확률론
Archives
- Today
- Total
히비스서커스의 블로그
[Pandas] dataframe에서 데이터 읽기 속도 관련 (feat. values vs iloc) 본문
Programming/Python
[Pandas] dataframe에서 데이터 읽기 속도 관련 (feat. values vs iloc)
HibisCircus 2024. 11. 20. 12:24728x90
파이썬에서 대용량 dataframe을 다루다 보면 시간이 오래걸릴 때가 있다. 대용량부터는 데이터를 효율적으로 읽어들이는 방법을 써야 시간을 아낄 수 있다. 이번에도 아니나 다를까 시간이 오래 걸려 코드를 개선하였는데 훨씬 더 빨라졌다.
기존 코드에 작성한 코드는 다음과 같다.
def __getitem__(self, idx):
item = {}
img_path = self.df.values[idx,1].replace('./','/data/nas_data/Public/dacon_mai/')
image = cv2.imread(img_path)
image = self.transform(image)
reduced_matrix = self.df.values[idx,2:].astype(float)
item['image'] = image.float() #color channel first, then XY
item['reduced_expression'] = torch.tensor(reduced_matrix).float() #cell x features (3467)
return item
dataframe에서 values 메서드를 통해 값을 가져왔다. 이때는 astype을 통해 데이터 형식 변환하였고 tensor로 변환해주었다.
개선된 코드는 다음과 같다.
def __getitem__(self, idx):
item = {}
img_path = self.df.iloc[idx,1].replace('./','/data/nas_data/Public/dacon_mai/')
image = cv2.imread(img_path)
image = self.transform(image)
reduced_matrix = self.df.iloc[idx,2:]
item['image'] = image.float() #color channel first, then XY
item['reduced_expression'] = torch.tensor(reduced_matrix,dtype=torch.float32) #cell x features (3467)
return item
dataframe에서 iloc 메서드를 통해서 읽어왔고 tensor로 변환해줄 때, dtype을 활용하였다.
속도가 유의미하게 빨라졌다. 10분 정도 소요되던 것이 10초도 안걸린다.
그 이유가 궁금하여 챗지피티한테 물어보았다.
코드를 수정한 후 속도가 빨라진 이유는 df.values와 df.iloc의 데이터 접근 방식 차이에서 비롯됩니다.
1. df.values 사용 시 느려지는 이유
df.values[idx, 2:]: df.values는 DataFrame의 데이터를 numpy.ndarray로 반환합니다. 이 방식은 전체 데이터셋을 NumPy 배열로 변환한 후 데이터를 가져오기 때문에, DataFrame에서 값을 추출할 때 항상 DataFrame의 모든 값을 한꺼번에 메모리에 로드하게 됩니다.데이터가 크면, 전체 데이터를 한 번에 가져오는 작업이 비용이 많이 듭니다.특히, **Pandas의 기본 데이터 타입(예: float64)**과 PyTorch의 torch.float32 간에 변환 작업이 추가적으로 필요할 수 있습니다.6992 x 3469 크기의 큰 데이터를 처리할 때, 매번 df.values로 NumPy 배열을 생성하고 나서 그 배열에서 값을 가져오면 메모리와 성능에서 부담이 커집니다.
2. df.iloc 사용 시 성능이 향상된 이유
df.iloc[idx, 2:]: iloc는 DataFrame에서 정수 기반 인덱싱을 사용하여 필요한 부분만 추출합니다. 이 방식은 데이터를 바로 Pandas의 내부 구조에서 접근하기 때문에, values처럼 전체 DataFrame을 메모리에 로드하지 않고, 필요한 부분만 접근합니다.더 효율적으로 데이터에 접근할 수 있습니다.또한, dtype=torch.float32를 사용하여 데이터 타입을 생성 시점에서 명시적으로 설정하므로, 불필요한 타입 변환 과정이 줄어듭니다.
주요 차이 요약:
**df.values**는 전체 DataFrame을 numpy.ndarray로 변환한 후 데이터에 접근하므로 전체 데이터를 메모리에 로드하는 데 시간이 많이 걸릴 수 있습니다.**df.iloc**는 정수 인덱스 기반으로 필요한 부분만 선택하므로 메모리 효율성이 높고, 데이터 접근 속도가 빨라집니다.
따라서, 수정된 코드에서는 iloc을 사용해 필요한 부분만 선택하고, 타입을 생성 시점에서 명시함으로써 더 효율적인 처리가 가능해져 속도가 빨라진 것입니다.
df.values는 df를 매번 불러오는데 df.iloc는 부분만 불러와서 속도가 더 빨라졌던 것이다. 이왕이면 values가 아닌 iloc를 활용하여 사용하자!
728x90
'Programming > Python' 카테고리의 다른 글
[HuggingFace] 허깅페이스 데이터 다운로드하기 (1) | 2024.11.10 |
---|---|
[Python] model의 FLOPs 계산하기 (feat.calflops) (1) | 2024.11.08 |
[Airflow] Docker 환경에서 Airflow와 PostgreSQL 활용하기 (0) | 2023.07.27 |
[Airflow] Docker 환경에서 Airflow와 Wandb 같이 활용하기 (0) | 2023.07.27 |
[mmdetection] mmdetection을 통한 object detection 데이터셋 커스터마이징 방법 (ver.3.1) (2) | 2023.07.25 |