Как извлечь элементы из каждой строки в файле jsonline? - PullRequest
2 голосов
/ 26 мая 2019

У меня есть файл jsonl, который содержит в каждой строке как предложение, так и токены, найденные в этом предложении. Я хочу извлечь токены из каждой строки в файле строк JSON, но мой цикл возвращает токены только из последней строки.

Это вход.

{"text":"This is the first sentence.","_input_hash":2083129218,"_task_hash":-536378640,"spans":[],"meta":{"score":0.5,"pattern":65},"answer":"accept","tokens":[
{"text":"This","id":0},
{"text":"is","id":1},
{"text":"the","id":2},
{"text":"first","id":3},
{"text":"sentence","id":4},
{"text":".","id":5}]}
{"text":"This is the second sentence.","_input_hash":2083129218,"_task_hash":-536378640,"spans":[],"meta":{"score":0.5,"pattern":65},"answer":"accept","tokens":[
{"text":"This","id":0},
{"text":"is","id":1},
{"text":"the","id":2},
{"text":"second","id":3},
{"text":"sentence","id":4},
{"text":".","id":5}]}

Я попытался запустить следующий код:

with jsonlines.open('path/to/file') as reader:
        for obj in reader:
        data = obj['tokens'] # just extract the tokens
        data = [(i['text'], i['id']) for i in data] # elements from the tokens

data

Фактический результат:

[('This', 0), («есть», 1), ('the', 2), («первый», 3), («предложение», 4), ('.', 5)]

Каков результат, к которому я хочу добраться:

enter image description here

Дополнительный вопрос

Некоторые токены содержат «метку» вместо «id». Как я могу включить это в код? Примером может быть:

{"text":"This is the first sentence.","_input_hash":2083129218,"_task_hash":-536378640,"spans":[],"meta":{"score":0.5,"pattern":65},"answer":"accept","tokens":[
{"text":"This","id":0},
{"text":"is","id":1},
{"text":"the","id":2},
{"text":"first","id":3},
{"text":"sentence","id":4},
{"text":".","id":5}]}
{"text":"This is coded in python.","_input_hash":2083129218,"_task_hash":-536378640,"spans":[],"meta":{"score":0.5,"pattern":65},"answer":"accept","tokens":[
{"text":"This","id":0},
{"text":"is","id":1},
{"text":"coded","id":2},
{"text":"in","id":3},
{"text":"python","label":"Programming"},
{"text":".","id":5}]}

Ответы [ 2 ]

1 голос
/ 26 мая 2019

Некоторые проблемы / изменения в коде

  • Вы повторно назначаете переменную data в цикле каждый раз, следовательно, вы видите результат только для последней строки json, вместо этого вы хотите расширять список каждый раз

  • Вы хотите использовать enumerate на итераторе reader, чтобы получить первый элемент кортежа

Затем код меняется на

import jsonlines

data = []
#Iterate over the json files
with jsonlines.open('file.txt') as reader:
    #Iterate over the each line on the reader via enumerate
    for idx, obj in enumerate(reader):

        #Append the data to the result
        data.extend([(idx+1, i['text'], i['id']+1) for i in obj['tokens']])  # elements from the tokens

print(data)

Или сделать более компактным, сделав двойной цикл for в самом понимании списка

import jsonlines

#Open the file, iterate over the tokens and make the tuples
result = [(idx+1, i['text'], i['id']+1) for idx, obj in enumerate(jsonlines.open('file.txt')) for i in obj['tokens']]

print(result)

Выход будет

[
(1, 'This', 1), 
(1, 'is', 2), 
(1, 'the', 3), 
(1, 'first', 4), 
(1, 'sentence', 5), 
(1, '.', 6), 
(2, 'This', 1), 
(2, 'is', 2), 
(2, 'the', 3), 
(2, 'second', 4), 
(2, 'sentence', 5), 
(2, '.', 6)
]
1 голос
/ 26 мая 2019
f=open('data.csv','w')
print('Sentence','Word','ID',file=f)
with jsonlines.open('path/to/file') as reader:
        for sentence_no,obj in enumerate(reader):
            data = obj['tokens']
            for i in data:
                print(sentence_no+1,i['text'], i['id']+1,file=f)
...