pythonjsonlogicfilesplitting

Split nested JSON File into two JSONs according to their ID?


I have nested JSON File which loaded as python dictionary called movies_data as follows:

with open('project_folder/data_movie_absa.json') as infile:
  movies_data = json.load(infile)

It has the following structure:

{ "review_1": {"tokens": ["Best", "show", "ever", "!"], 
               "movie_user_4": {"aspects": ["O", "B_A", "O", "O"], "sentiments": ["B_S", "O", "O", "O"]},  
               "movie_user_6": {"aspects": ["O", "B_A", "O", "O"], "sentiments": ["B_S", "O", "O", "O"]}}, 

  "review_2": {"tokens": ["Its", "a", "great", "show"], 
               "movie_user_1": {"aspects": ["O", "O", "O", "B_A"], "sentiments": ["O", "O", "B_S", "O"]}, 
               "movie_user_6": {"aspects": ["O", "O", "O", "B_A"], "sentiments": ["O", "O", "B_S", "O"]}},

  "review_3": {"tokens": ["I", "love", "this", "actor", "!"],  
               "movie_user_17": {"aspects": ["O", "O", "O", "B_A", "O"], "sentiments": ["O", "B_S", "O", "O", "O"]}, 
               "movie_user_23": {"aspects": ["O", "O", "O", "B_A", "O"], "sentiments": ["O", "B_S", "O", "O", "O"]}},

  "review_4": {"tokens": ["Bad", "movie"], 
               "movie_user_1": {"aspects": ["O", "B_A"], "sentiments": ["B_S", "O"]}, 
               "movie_user_6": {"aspects": ["O", "B_A"], "sentiments": ["B_S", "O"]}}

...
}

It has 3324 key-value pairs (i.e., up to key review_3224). I want to split this file into two json files (train_movies.json, test_movies.json) based on specific list of keys:

test_IDS = ['review_2', 'review_4']

with open("train_movies.json", "w", encoding="utf-8-sig") as outfile_train, open("test_movies.json", "w", encoding="utf-8-sig") as outfile_test:
  for review_id, review in movies_data.items():
    if review_id in test_IDS:
      outfile = outfile_test
      outfile.write('{"%s": "%s"}' % (review_id, movies_data[review_id]))
      
    else:
      outfile = outfile_train
      outfile.write('{"%s": "%s"}' % (review_id, movies_data[review_id]))
  outfile.close()

for test_movies.json I have the following structure:

{"review_2": "{'tokens': ['Its', 'a', 'great', 'show'], 
            'movie_user_4': {'aspects': ['O', 'O', 'O', 'B_A'], 'sentiments': ['O', 'O', 'B_S', 'O']}, 
            'movie_user_6': {'aspects': ['O', 'O', 'O', 'B_A'], 'sentiments': ['O', 'O', 'B_S', 'O']}}"}

{"review_4": "{'tokens': ['Bad', 'movie'], 
               'movie_user_1': {'aspects': ['O', 'B_A'], 'sentiments': ['B_S', 'O']},
               'movie_user_6': {'aspects': ['O', 'B_A'], 'sentiments': ['B_S', 'O']}}"}

Unfortunately, this structure has some problems like inconsistent double quotes (" vs. '), no commas between reviews etc... Therefore, I have the following problem by reading test_movies.json as json file:

with open('project_folder/test_movies.json') as infile:
  testing_data = json.load(infile)

The error message:


JSONDecodeError                           Traceback (most recent call last)
<ipython-input-10-3548a718f421> in <module>()
      1 with open('/content/gdrive/My Drive/project_folder/test_movies.json') as infile:
----> 2   testing_data = json.load(infile)

1 frames
/usr/lib/python3.6/json/__init__.py in loads(s, encoding, cls, object_hook, parse_float, parse_int, parse_constant, object_pairs_hook, **kw)
    342         if s.startswith('\ufeff'):
    343             raise JSONDecodeError("Unexpected UTF-8 BOM (decode using utf-8-sig)",
--> 344                                   s, 0)
    345     else:
    346         if not isinstance(s, (bytes, bytearray)):

JSONDecodeError: Unexpected UTF-8 BOM (decode using utf-8-sig): line 1 column 1 (char 0)

The desired output should have a correct json structure like the original movies_data so python could read it correctly as a dict.

Could you help me please to correct my python code?

Thank you in advance!


Solution

  • Issue

    Code

    train, test = {}, {}   # Dicionaries for storing training and test data
    for review_id, review in movies_data.items():
        if review_id in test_IDS:
            test[review_id] = review
        else:
            train[review_id] = review
    
    # Output Test
    with open("test_movies.json", "w") as outfile_test:
        json.dump(test, outfile_test)
        
    # Output training
    with open("train_movies.json", "w") as outfile_train:
        json.dump(train, outfile_train)
    

    Results

    Input: File Contents of test.json

    { "review_1": {"tokens": ["Best", "show", "ever", "!"], 
                   "movie_user_4": {"aspects": ["O", "B_A", "O", "O"], "sentiments": ["B_S", "O", "O", "O"]},  
                   "movie_user_6": {"aspects": ["O", "B_A", "O", "O"], "sentiments": ["B_S", "O", "O", "O"]}}, 
    
      "review_2": {"tokens": ["Its", "a", "great", "show"], 
                   "movie_user_1": {"aspects": ["O", "O", "O", "B_A"], "sentiments": ["O", "O", "B_S", "O"]}, 
                   "movie_user_6": {"aspects": ["O", "O", "O", "B_A"], "sentiments": ["O", "O", "B_S", "O"]}},
    
      "review_3": {"tokens": ["I", "love", "this", "actor", "!"],  
                   "movie_user_17": {"aspects": ["O", "O", "O", "B_A", "O"], "sentiments": ["O", "B_S", "O", "O", "O"]}, 
                   "movie_user_23": {"aspects": ["O", "O", "O", "B_A", "O"], "sentiments": ["O", "B_S", "O", "O", "O"]}},
    
      "review_4": {"tokens": ["Bad", "movie"], 
                   "movie_user_1": {"aspects": ["O", "B_A"], "sentiments": ["B_S", "O"]}, 
                   "movie_user_6": {"aspects": ["O", "B_A"], "sentiments": ["B_S", "O"]}}
    
    }
    

    Output: File Contents of test_movies.json

    {"review_2": {"tokens": ["Its", "a", "great", "show"], "movie_user_1": {"aspects": ["O", "O", "O", "B_A"], "sentiments": ["O", "O", "B_S", "O"]}, "movie_user_6": {"aspects": ["O", "O", "O", "B_A"], "sentiments": ["O", "O", "B_S", "O"]}}, "review_4": {"tokens": ["Bad", "movie"], "movie_user_1": {"aspects": ["O", "B_A"], "sentiments": ["B_S", "O"]}, "movie_user_6": {"aspects": ["O", "B_A"], "sentiments": ["B_S", "O"]}}}
    

    Output: File Contents of train_movies.json

    {"review_1": {"tokens": ["Best", "show", "ever", "!"], "movie_user_4": {"aspects": ["O", "B_A", "O", "O"], "sentiments": ["B_S", "O", "O", "O"]}, "movie_user_6": {"aspects": ["O", "B_A", "O", "O"], "sentiments": ["B_S", "O", "O", "O"]}}, "review_3": {"tokens": ["I", "love", "this", "actor", "!"], "movie_user_17": {"aspects": ["O", "O", "O", "B_A", "O"], "sentiments": ["O", "B_S", "O", "O", "O"]}, "movie_user_23": {"aspects": ["O", "O", "O", "B_A", "O"], "sentiments": ["O", "B_S", "O", "O", "O"]}}}