Ładowanie pliku z więcej niż jedną linią JSON do Pandas

92

Próbuję wczytać w pliku JSON do ramki danych Python pandas (0.14.0). Oto pierwsza linia pliku JSON:

{"votes": {"funny": 0, "useful": 0, "cool": 0}, "user_id": "P_Mk0ygOilLJo4_WEvabAA", "review_id": "OeT5kgUOe3vcN7H6ImVmZQ", "stars": 3, "date": "2005-08-26", "text": "This is a pretty typical cafe.  The sandwiches and wraps are good but a little overpriced and the food items are the same.  The chicken caesar salad wrap is my favorite here but everything else is pretty much par for the course.", "type": "review", "business_id": "Jp9svt7sRT4zwdbzQ8KQmw"}

Próbuję wykonać następujące czynności: df = pd.read_json(path).

Otrzymuję następujący błąd (z pełnym śledzeniem):

Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/Users/d/anaconda/lib/python2.7/site-packages/pandas/io/json.py", line 198, in read_json
    date_unit).parse()
  File "/Users/d/anaconda/lib/python2.7/site-packages/pandas/io/json.py", line 266, in parse
    self._parse_no_numpy()
  File "/Users/d/anaconda/lib/python2.7/site-packages/pandas/io/json.py", line 483, in _parse_no_numpy
    loads(json, precise_float=self.precise_float), dtype=None)
ValueError: Trailing data

Jaki jest Trailing databłąd? Jak wczytać to do ramki danych?

Zgodnie z kilkoma sugestiami, oto kilka wierszy pliku .json:

{"votes": {"funny": 0, "useful": 0, "cool": 0}, "user_id": "P_Mk0ygOilLJo4_WEvabAA", "review_id": "OeT5kgUOe3vcN7H6ImVmZQ", "stars": 3, "date": "2005-08-26", "text": "This is a pretty typical cafe.  The sandwiches and wraps are good but a little overpriced and the food items are the same.  The chicken caesar salad wrap is my favorite here but everything else is pretty much par for the course.", "type": "review", "business_id": "Jp9svt7sRT4zwdbzQ8KQmw"}
{"votes": {"funny": 0, "useful": 0, "cool": 0}, "user_id": "TNJRTBrl0yjtpAACr1Bthg", "review_id": "qq3zF2dDUh3EjMDuKBqhEA", "stars": 3, "date": "2005-11-23", "text": "I agree with other reviewers - this is a pretty typical financial district cafe.  However, they have fantastic pies.  I ordered three pies for an office event (apple, pumpkin cheesecake, and pecan) - all were delicious, particularly the cheesecake.  The sucker weighed in about 4 pounds - no joke.\n\nNo surprises on the cafe side - great pies and cakes from the catering business.", "type": "review", "business_id": "Jp9svt7sRT4zwdbzQ8KQmw"}
{"votes": {"funny": 0, "useful": 0, "cool": 0}, "user_id": "H_mngeK3DmjlOu595zZMsA", "review_id": "i3eQTINJXe3WUmyIpvhE9w", "stars": 3, "date": "2005-11-23", "text": "Decent enough food, but very overpriced. Just a large soup is almost $5. Their specials are $6.50, and with an overpriced soda or juice, it's approaching $10. A bit much for a cafe lunch!", "type": "review", "business_id": "Jp9svt7sRT4zwdbzQ8KQmw"}

Ten plik .json, którego używam, zawiera jeden obiekt JSON w każdym wierszu, zgodnie ze specyfikacją.

Wypróbowałem witrynę jsonlint.com zgodnie z sugestią i wyświetla następujący błąd:

Parse error on line 14:
...t7sRT4zwdbzQ8KQmw"}{    "votes": {
----------------------^
Expecting 'EOF', '}', ',', ']'
user62198
źródło
1
Masz dodatkowe dane w pliku, które nie są częścią obiektu JSON.
Martijn Pieters
Jak wygląda kilka ostatnich wierszy pliku json?
Bryan Oakley
2
Ten przykład dobrze mi pasuje w pandach 0.16.0. Jakiej wersji pand używasz?
Andy Hayden
1
@ user62198 aktualizacja do wersji 0.16.0, pojawiło się kilka poprawek do read_json.
Andy Hayden
1
@Cornel Ghiban, mogę załadować cały plik lub przeczytać w pojedynczej linii. Wygląda na to, że konwersja do wspomnianego formatu może być nieco trudna, ponieważ takich płyt jest ponad 5 milionów.
user62198

Odpowiedzi:

240

Od wersji 0.19.0 Pandas możesz użyć linesparametru, takiego jak:

import pandas as pd

data = pd.read_json('/path/to/file.json', lines=True)
Andrzej
źródło
Masz jakiś pomysł, jak obejść ten problem związany z linesargumentem? github.com/pandas-dev/pandas/issues/15132
Chuck
33

Musisz to przeczytać linijka po linijce. Na przykład możesz użyć następującego kodu dostarczonego przez ryptophan na reddit :

import pandas as pd

# read the entire file into a python array
with open('your.json', 'rb') as f:
    data = f.readlines()

# remove the trailing "\n" from each line
data = map(lambda x: x.rstrip(), data)

# each element of 'data' is an individual JSON object.
# i want to convert it into an *array* of JSON objects
# which, in and of itself, is one large JSON object
# basically... add square brackets to the beginning
# and end, and have all the individual business JSON objects
# separated by a comma
data_json_str = "[" + ','.join(data) + "]"

# now, load it into pandas
data_df = pd.read_json(data_json_str)
Artem
źródło
Cześć, próbuję odczytać plik json un i przechowywać w ramce danych. Jednak gdy użyłem twojego kodu, pojawił się błąd: „TypeError: sekwencja pozycja 0: oczekiwana instancja str, znalezione bajty”. Czy wiesz, co z tym nie tak?
ngoduyvu
3

Poniższy kod pomógł mi załadować JSONzawartość do dataframe:

import json
import pandas as pd

with open('Appointment.json', encoding="utf8") as f:
    data = f.readlines()
    data = [json.loads(line) for line in data] #convert string to dict format
df = pd.read_json(data) # Load into dataframe
Triguna
źródło
1

Miałem podobny problem.

Okazuje się, że pd.read_json(myfile.json)automatycznie przeszuka folder nadrzędny, ale zwraca ten błąd „danych końcowych”, jeśli nie znajdujesz się w tym samym folderze co plik.

Rozgryzłem to, bo jak próbowałem to zrobić open('myfile.json', 'r')i wyskoczył mi FileNotFoundbłąd to sprawdziłem ścieżki.

Nie udało mi się przenieść pliku myfile.json do tego samego folderu co mój notatnik.

Zmieniam to na pd.read_json('../myfile.json')po prostu działające.

szeitlin
źródło
1
To głupie, że daje, ValueError: Trailing datakiedy powinien dać FileNotFound. Mnie też się to przydarzyło.
ProGirlXOXO