[Python] Json Line

전보·2020년 5월 18일
0

Jsonl

회사에서 데이터를 받아서 처리하는 일을 하다가, jsonl이라는 형식을 알게되었다.
처음에는 .json파일에 데이터로그가 잘 못 찍힌거구나, 라고 생각해서 팀장한테 json파일형식이 이상하다고 했지만, 알고보니 jsonl이라는 형식이었다.

한국자료에는 잘 안나와있어서 그래도 아래의 링크에 있는 내용이 가장 이해하기 쉬웠기 때문에 참고해서 포스팅했다.

첫번째 링크는 일반적인 json라이브러리로 사용할 수 있는 방법이고,
두번째 링크는 jsonlines라는 라이브러리를 따로 만들어서 사용할 수 있도록 공유해놓은 자료이다.

How to Love jsonl — using JSON Lines in your Workflow
jsonlines라이브러리를 이용방법.

Json Line 형식이란?

각 라인이 Json객체로 이루어진 파일 형식이다. 쉽게 생각하면 한줄에 사전하나씩 여러개가 같이 있는 것.
다음은 4개의 객체가 있는 예이다.

#jsonfile.jsonl

{"name": "Gilbert", "wins": [["straight", "7♣"], ["one pair", "10♥"]]}
{"name": "Alexa", "wins": [["two pair", "4♠"], ["two pair", "9♠"]]}
{"name": "May", "wins": []}
{"name": "Deloise", "wins": [["three of a kind", "5♣"]]}

사실이렇게 한줄에 하나씩있어야되는데, 내가 회사에서 받은 json파일은 라인이 엉망이어서 안그래도 파이썬도 잘 못하는데 처음에는 뭐가 잘못된 줄 몰라 답답했었다.

아래와 같이 json line을 정의하기위해서 몇가지 규칙이있다.(http://jsonlines.org/)
1. UTF-8 인코딩일 것.
2. 각 줄은 유효한 json형식이어야 한다.
3. 줄 바꾸기 문자 "\n"으로 각 객체를 구분한다.

jsonl을 읽고 쓰는데 사용할 수 있는 코드는 아래페이지를 참조하세요.
How to Love jsonl — using JSON Lines in your Workflow

실습

나는 처음에 라인이 정리가안된 jsonl파일을 받았기 때문에 위의 코드를 그대로 대입시켜봤을 때 정상적으로 실행되지 않았다.

참고로 내가 받았던 json파일은 예를 들자면 다음과 같이 생겼었다.

#test.json

{"Number":"21","Id":124,"Results":[{"code":0,"data":[[1,true],[2,false]]}],"version":"1.2"}{
  "Imp": [
    {
      "Version": "v3",
      "data": "2323"
    }
  ]
}

개행이 엉망진창이었다..근데 이렇게생긴 파일 수백개의 데이터를 뽑아냈어야 됬기 때문에 하나하나 고칠 수는 없었다.

json.loads()함수를 쓸 수 없었다.
그래서 어쩔 수 없이 이렇게 썼다.

data = []
with open('test.json', 'r', encoding='utf-8') as f:
    for line in f:
        data.append(line) #라인을 기준으로 일단 자름.
'''
위의 json파일을 보면 알 수 있듯이 첫째줄을 보면 끝이 "}{" 이렇게 되어있다.
그래서 0번째 라인에서 마지막 두글자({, \n)를 빼고 다시 대입해서 저장.
'''
obj1 = data[0][:-2]
obj2 = "{" + "".join(data[1:])  #두번째 오브젝트 줄에는 시작{가 빠져있으므로

#여기는 '\n'문자가 있으면 빼주는 for문, 빼고나서 다시 join으로 합치기
data_list =list(obj2)
for i, data in enumerate(data_list):
    if data == "\n":
        data_list.pop(i)
obj2 = "".join(data_list[:-1]) #[:-1]을 해준이유는 마지막에 이상한 space문자가 들어가있어서 빼줬다. 통상은 안해도 될 듯.

#정리된 객체의 str -> json 으로 바꿔주기.
data_dic1 = json.loads(obj1)
data_dic2 = json.loads(obj2)
profile
엉망진창

0개의 댓글