///////
Search

Java로 대용량 데이터 분석하기_이도현

주제 : Java로 대용량 데이터 분석하기 프로젝트
목표 : MIDS에서 받은 인구이동 데이터로 2021 서울에서 가장 많이 이사간 지역은 어디인지 알아내기
필요한 과정
기능/메소드
도전 과제
보충 개념

1. 대용량 데이터 500MB 읽기

1.
데이터 파일 다운로드 받아 읽어오기 (MDIS)
a.
메타데이터 : 데이터를 설명하는 데이터
b.
, 로 데이터 속성을 구분한 CSV 확장자 파일을 자바의 Object로 바꾸어 메모리로 읽어와야 함
c.
한 줄씩 line 읽어오는 BufferedReader 활용
d.
파일 위치 읽기 : 파일 위에서 마우스 오른쪽 클릭 > 속성 > 일반 > 위치
기존에 쓰던 코드 void 메소드로 분리
코드_PopulationStatistics
2.
클래스 생성
코드_PopulationMove

2. 데이터 메모리에 올리기

1.
데이터 파싱
a.
CSV 파일은 데이터를 ‘,’ 로 구분하므로 ‘,’로 데이터를 분해
b.
PopulationMove 생성자 오버로딩
2.
파싱한 PopulationMove 객체를 List에 저장
코드_PopulationStatistics_2
코드_PopulationMove_2

3. 파일 생성, 쓰기, 저장

목적 : 데이터를 더 효율적으로 저장하고 다루기 위함
2.
파일 쓰기
코드_PopulationStatistics_3

4. 저장한 파일 로드, 파싱하기

코드_PopulationStatistics_4

5. 지역별 이사 횟수 count

Map 사용한 getMoveCntMap 메소드 만들기
코드_PopulationStatistics_5

최종 (히트맵에 맞게 매핑 추가)

package week3.practice.dataproject; import java.io.*; import java.util.*; public class PopulationStatistics { private String address; //초기화 //4단계. parse() 로직 refactor public PopulationMove parse(String str) { //파일 한 줄을 매개변수로 String[] splittedLine = str.split(","); //, 기준으로 분리 후 String[]으로 반환 return new PopulationMove(splittedLine[0], splittedLine[1]); //fromsido, tosido } public PopulationStatistics(String address) { //address를 매개변수로 하는 생성자 this.address = address; } //삽으로 푸듯 크게 한 줄씩 읽기 //1-1단계. 시도1 : 한 줄 읽기 메소드. 공간 복잡도가 늘어남 //FileReader fileReader = new FileReader(filename); //BufferedReader reader = new BufferedReader(fileReader); /* public void readByLine(String filename) throws IOException{ BufferedReader reader = new BufferedReader(new FileReader(filename)); //객체 생성 while((str = reader.readLine()) != null) { //파일 내용 한 줄씩 출력 System.out.println(str); } reader.close(); }*/ //2단계. refactor : 반환형을 list<PopulationMove>로 변경 public List<PopulationMove> readFileByLine(String filename) throws IOException { List<PopulationMove> pml = new ArrayList<>(); BufferedReader reader = new BufferedReader(new FileReader(filename)); String str = ""; while ((str = reader.readLine()) != null) { PopulationMove populationMove = parse(str); pml.add(populationMove); //리스트에 저장 } reader.close(); return pml; //PopulationMove 리스트 반환 } //3-1단계. 파일 생성 메소드 작성 > 루트 디렉토리 위치에 파일 생성 public void createAFile(String filename) { File file = new File(filename); try { //try-catch file.createNewFile(); } catch (IOException e) { throw new RuntimeException(e); } } //3-2단계. 리스트 객체의 내용을 새 파일에 입력 public void write(List<String> strs, String filename) { File file = new File(filename); try { //try-catch BufferedWriter writer = new BufferedWriter(new FileWriter(filename)); for (String str : strs) { writer.write(str); } writer.close(); } catch (IOException e) { e.printStackTrace(); //예외 상황 분석 용도 //.printStackTrace()는 예외 발생 당시의 호출스택에 있던 메소드의 정보와 예외 결과 출력 } } //6단계. 히트맵에 맞게 매핑 public String fromToString(PopulationMove populationMove) { return populationMove.getFromSido() + "," + populationMove.getToSido()+"\n"; } public Set<Integer> printSidoCd(List<PopulationMove> populationMoveList) { Set<Integer> intSet = new HashSet<>(); for (PopulationMove pm : populationMoveList) { intSet.add(pm.getToSido()); intSet.add(pm.getFromSido()); } System.out.println(intSet); return intSet; } /*(5단계. List<Population>을 매개변수로 하는 getMoveCntMapㅁ메서드 로직 1. listpopulationmove를 순환하면서 "11:26" 형태의 key를 만든다. 2. moveCntMap에서 해당 key에 해당하는 Object가 없으면 생성하고 1이라고 체크 3. key로 꺼내서 +1 4. 리턴 moveCntMap) */ public Map<String, Integer> getMoveCntMap(List<PopulationMove> pml) { Map<String, Integer> moveCntMap = new HashMap<>(); for(PopulationMove pm : pml) { String key = pm.getFromSido() + "," + pm.getToSido(); if(moveCntMap.get(key) == null) { moveCntMap.put(key, 1); } moveCntMap.put(key, moveCntMap.get(key)+1); } return moveCntMap; } public Map<String, Integer> heatmapIdxMap() { Map<String, Integer> heatmap = new HashMap<>(); //각 시,도 코드를 초기화 heatmap.put("11",0); heatmap.put("26",1); heatmap.put("27",2); heatmap.put("28",3); heatmap.put("29",4); heatmap.put("30",5); heatmap.put("31",6); heatmap.put("36",7); heatmap.put("41",8); heatmap.put("42",9); heatmap.put("43",10); heatmap.put("44",11); heatmap.put("45",12); heatmap.put("46",13); heatmap.put("47",14); heatmap.put("48",15); heatmap.put("50",16); return heatmap; } /* public void readByLine2(String filename) { //1-2단계. 시도2 : 에러를 try-catch로 처리 try (BufferedReader br = Files.newBufferedReader(Paths.get(filename), StandardCharsets.UTF_8)) { String line, str; while ((line = br.readLine()) != null) { System.out.println(line); } catch(IOException e){ throw new RuntimeException(e); } } */ //메인 public static void main(String[] args) throws IOException { String address = "C:\\-\\git\\src\\week3\\day5_fri";//파일경로 PopulationStatistics ps = new PopulationStatistics(address); //2단계. statistics.readByLine(address);를 리스트 객체에 맞게 Refactor List<PopulationMove> pml = ps.readFileByLine(address); //5단계. file 생성 refactor Map <String,Integer> map = ps.getMoveCntMap(pml); //6단계. heatmap 파일 생성 Map <String, Integer> heatMapIdxMap = ps.heatmapIdxMap(); String targetFilename = "for_heatmap.txt"; ps.createAFile(targetFilename); //파일생성 List<String> cntResult = new ArrayList<>(); for(String key : map.keySet()) { String[] fromto = key.split(","); //매핑 후 저장 String s = String.format("[%s, %s, %d],\n", heatmapIdxMap.get(fromto[0]), heatmapIdxMap.get(fromto[1]), map.get(key)); cntResult.add(s); //String s = "key:" + key + ", value:" + map.get(key)+ "\n"; } ps.write(cntResult, targetFilename); } }
Java
복사
새로 알게 된 것