Чтение указанного c количества случайно выбранных json записей - PullRequest
1 голос
/ 08 июля 2020

Вопрос о Python3 / Jupyter Notebook. У меня большой json (> 3 млн записей). Я пытаюсь прочитать 50 000 случайных записей в списке с требованием, чтобы эти случайные записи имели параметр «country_code» со значением c. Прямо сейчас я читаю каждую из 3 миллионов записей, сужаюсь до записей с правильным кодом страны, а затем беру 50 000 случайных элементов из этого подсписка. Я бы хотел прочитать только 50 000 случайных строк с правильным кодом страны вместо того, чтобы сначала go пройти через все 3 миллиона. Текущий метод занимает слишком много времени.

Мой текущий код:

def filter_json_by_country(filename, country):
    file = Path(filename)
    data = list()
    
    with file.open('r') as f:
        for line in f:
            data.append(json.loads(line))

    loc_filtered_data = []
    for i in range(len(data)):
        if len(data[i]['user_location']) != 0 and data[i]['user_location']['country_code'] == country:
            loc_filtered_data.append(data[i])

    ids = [loc_filtered_data[i]['tweet_id'] for i in range(len(loc_filtered_data))]
    ids = random.sample(ids, 50000) 
    return ids

EDITED - json образец:

{
     "tweet_id":"1231698465102663680",
     "created_at":"Sun Feb 23 21:52:52 +0000 2020",
     "user_id":"433036746",
     "geo_source":"tweet_text",
     "user_location":{},
     "geo":{},
     "place":{},
     "tweet_locations":
        [
            {
                "country_code":"us",
                "state":"Illinois"},
            {
                "country_code":"fr",
                "state":"Auvergne-Rh\u00f4ne-Alpes",
                "county":"Die"},
            {
                "country_code":"it",
                "state":"Piemont",
                "county":"TO",
                "city":"Porte"},
            {
                "country_code":"fr",
                "state":"Occitania",
                "county":"Castres",
                "city":"Lacaze"},
            {
                "country_code":"br",
                "state":"Sergipe",
                "county":"Microrregi\u00e3o do Baixo S\u00e3o Francisco Sergipano",
                "city":"Propri\u00e1"}
        ]
}

Ответы [ 2 ]

0 голосов
/ 08 июля 2020
• 1000 data.

Вот тот, который включает рандомизацию в тот же l oop:

def filter_json_by_country(filename, country):    
    loc_filtered_data = []
    length = -1
    with open(filename, 'r') as f:
        for length, l in enumerate(f):
            pass
        
        # Do randomizing before loading json
        shuffled = list(range(length + 1))
        random.shuffle(shuffled)

        for i in shuffled:
            if len(loc_filtered_data) >= 50_000:
                break
            f.seek(i, 0)
            data = json.loads(f.readline())
            
            # only append data if it satisfy the requirements
            if len(data['user_location']) != 0 and data['user_location']['country_code'] == country:
                loc_filtered_data.append(data[i])

    ids = [loc_filtered_data[i]['tweet_id'] for i in range(len(loc_filtered_data))]
    
    return ids

Скорость seek ing зависит от машины. Если вы сможете определить количество строк в файле быстрее, чем это, это будет еще быстрее. Но идея здесь в том, что вам нужно будет перебрать ровно 50 000 действительных записей (больше, если есть недействительные записи).

0 голосов
/ 08 июля 2020

Зачем использовать json с разделением строк?

Если вы рассчитываете время для своей функции, скорее всего, загрузка json займет 99% времени. Рассматривали ли вы использование какой-то таблицы, которая разрешила бы произвольный доступ, а не заставляла бы вас фильтровать впоследствии?

Если вы должны сохранить формат json, попробуйте загрузить его, обработать, а затем загрузить для маринованного файла я видел разумную производительность при таком интеллектуальном кэшировании.

В качестве другой альтернативы попробуйте найти код страны перед синтаксическим анализом с помощью json (поиск подстроки или даже 'grep').

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...