하나의 파일에서 여러 JSON 개체를 추출하려면 어떻게 해야 합니까?
저는 Json 파일을 매우 처음 접합니다.다음과 같은 여러 json 개체가 있는 json 파일이 있는 경우:
{"ID":"12345","Timestamp":"20140101", "Usefulness":"Yes",
"Code":[{"event1":"A","result":"1"},…]}
{"ID":"1A35B","Timestamp":"20140102", "Usefulness":"No",
"Code":[{"event1":"B","result":"1"},…]}
{"ID":"AA356","Timestamp":"20140103", "Usefulness":"No",
"Code":[{"event1":"B","result":"0"},…]}
…
모든 "Timestamp" 및 "유용성"을 데이터 프레임으로 추출합니다.
Timestamp Usefulness
0 20140101 Yes
1 20140102 No
2 20140103 No
…
그런 문제에 대한 일반적인 대처법을 아는 사람이 있나요?
업데이트: 파일 전체를 한 번에 읽을 필요가 없는 솔루션을 작성했습니다.stackoverflow 응답에는 너무 크지만, 여기서 확인할 수 있습니다.
사용할 수 있습니다.json.JSONDecoder.raw_decode
(메모리에 들어갈 수 있는 한) JSON의 큰 문자열을 임의로 디코딩합니다. raw_decode
유효한 개체가 있으면 중지하고 구문 분석된 개체의 일부가 아닌 마지막 위치를 반환합니다.문서화되어 있지는 않지만, 이 포지션을 다음 주소로 넘겨줄 수 있습니다.raw_decode
그 위치에서 다시 파싱이 시작됩니다.불행히도 파이썬은json
모듈은 프리픽스 공백이 있는 문자열을 받아들이지 않습니다.따라서 문서의 첫 번째 공백 이외의 부분을 검색해야 합니다.
from json import JSONDecoder, JSONDecodeError
import re
NOT_WHITESPACE = re.compile(r'\S')
def decode_stacked(document, pos=0, decoder=JSONDecoder()):
while True:
match = NOT_WHITESPACE.search(document, pos)
if not match:
return
pos = match.start()
try:
obj, pos = decoder.raw_decode(document, pos)
except JSONDecodeError:
# do something sensible if there's some error
raise
yield obj
s = """
{"a": 1}
[
1
,
2
]
"""
for obj in decode_stacked(s):
print(obj)
인쇄:
{'a': 1}
[1, 2]
다음 형식의 json 어레이를 사용합니다.
[
{"ID":"12345","Timestamp":"20140101", "Usefulness":"Yes",
"Code":[{"event1":"A","result":"1"},…]},
{"ID":"1A35B","Timestamp":"20140102", "Usefulness":"No",
"Code":[{"event1":"B","result":"1"},…]},
{"ID":"AA356","Timestamp":"20140103", "Usefulness":"No",
"Code":[{"event1":"B","result":"0"},…]},
...
]
그런 다음 python 코드로 Import합니다.
import json
with open('file.json') as json_file:
data = json.load(json_file)
데이터의 내용은 각 요소를 나타내는 사전이 있는 배열입니다.
다음과 같이 쉽게 접근할 수 있습니다.
data[0]["ID"]
따라서 어레이에 데이터를 포함하는 몇 가지 코멘트에서 설명한 것처럼 단순하지만 데이터 세트 크기가 커질수록 솔루션의 효율성은 향상되지 않습니다.배열 내의 임의의 항목에 액세스하려면 반복 가능한 개체만 사용해야 합니다. 그렇지 않으면 생성기를 사용하는 것이 좋습니다.아래에서는 각 json 객체를 개별적으로 읽고 제너레이터를 반환하는 리더 기능을 프로토타입으로 만들었습니다.
기본 아이디어는 판독기가 캐리지 문자를 분할하도록 신호하는 것입니다."\n"
(또는"\r\n"
를 참조해 주세요).Python은 이 기능을 사용할 수 있습니다.
import json
def json_reader(filename):
with open(filename) as f:
for line in f:
yield json.loads(line)
그러나 이 방법은 파일이 있는 그대로 작성되었을 때만 작동합니다.각 오브젝트는 줄 바꿈 문자로 구분됩니다.아래에 json 오브젝트의 배열을 구분하여 각 오브젝트를 새로운 행에 저장하는 라이터의 예를 작성했습니다.
def json_writer(file, json_objects):
with open(file, "w") as f:
for jsonobj in json_objects:
jsonstr = json.dumps(jsonobj)
f.write(jsonstr + "\n")
및 목록 이해에서도 동일한 작업을 수행할 수 있습니다.
...
json_strs = [json.dumps(j) + "\n" for j in json_objects]
f.writelines(json_strs)
...
, 그냥 해 주세요.open(file, "w")
로로 합니다.open(file, "a")
.
결과적으로 텍스트 에디터로 json 파일을 열 때 읽기 쉬울 뿐만 아니라 메모리를 보다 효율적으로 사용하는 데에도 큰 도움이 됩니다.
이 점에 있어서, 어느 시점에서 마음이 바뀌어 리더로부터 리스트를 꺼내고 싶은 경우, Python은 리스트의 내부에 생성 함수를 넣어 자동적으로 리스트를 채울 수 있습니다.즉, 그냥 쓰세요.
lst = list(json_reader(file))
@dunes의 답변에 따라 스트리밍 지원이 추가되었습니다.
import re
from json import JSONDecoder, JSONDecodeError
NOT_WHITESPACE = re.compile(r"[^\s]")
def stream_json(file_obj, buf_size=1024, decoder=JSONDecoder()):
buf = ""
ex = None
while True:
block = file_obj.read(buf_size)
if not block:
break
buf += block
pos = 0
while True:
match = NOT_WHITESPACE.search(buf, pos)
if not match:
break
pos = match.start()
try:
obj, pos = decoder.raw_decode(buf, pos)
except JSONDecodeError as e:
ex = e
break
else:
ex = None
yield obj
buf = buf[pos:]
if ex is not None:
raise ex
언급URL : https://stackoverflow.com/questions/27907633/how-to-extract-multiple-json-objects-from-one-file
'programing' 카테고리의 다른 글
Oracle 드롭 인덱스(존재하는 경우) (0) | 2023.03.12 |
---|---|
MongoParseError: useCreateIndex, useFindAndModify 옵션은 지원되지 않습니다. (0) | 2023.03.12 |
JSON 시리얼화 불가 (0) | 2023.03.12 |
Ajax 링크 요청을 보호하는 방법 (0) | 2023.03.12 |
유형에서 속성 제외 (0) | 2023.03.12 |