У меня скорость / эффективность связанный вопрос о Python :
Мне нужно извлечь несколько полей из вложенного файла JSON (после записи в .txt
файлы, они имеют ~ 64k строк, и текущий фрагмент делает это за ~ 9 минут ), где каждая строка может содержать плавающие и строковые значения.
Обычно япросто поместил бы все мои данные в numpy
и использовал бы np.savetxt()
для его сохранения ..
Я прибег к простой сборке строк в виде строк, но это немного медленный .Пока что я делаю:
- Собрать каждую строку в виде строки (извлечь нужное поле из JSON)
- Записать строку в соответствующий файл
У меня есть несколько проблем с этим: - это приводит к более отдельным file.write()
командам, которые тоже очень медленные .. (около 64k * 8 вызовов (для 8 файлов))
Итак, мой вопрос:
- Какова хорошая рутина для такого рода проблем?Тот, который уравновешивает
speed vs memory-consumption
для наиболее эффективной записи на диск. - Должен ли я увеличить
DEFAULT_BUFFER_SIZE
?(сейчас 8192)
Я проверил Файловый ввод / вывод на каждом языке программирования и python org: IO , но это не сильно помоглокроме (в моем понимании после прохождения через него файл io уже должен быть буферизован в python 3.6.x), и я обнаружил, что по умолчанию DEFAULT_BUFFER_SIZE
составляет 8192
.
Заранее спасибо за помощь !!
Вот часть моего фрагмента -
def read_json_line(line=None):
result = None
try:
result = json.loads(line)
except Exception as e:
# Find the offending character index:
idx_to_replace = int(str(e).split(' ')[-1].replace(')',''))
# Remove the offending character:
new_line = list(line)
new_line[idx_to_replace] = ' '
new_line = ''.join(new_line)
return read_json_line(line=new_line)
return result
def extract_features_and_write(path_to_data, inp_filename, is_train=True):
# It's currently having 8 lines of file.write(), which is probably making it slow as writing to disk is involving a lot of overheads as well
features = ['meta_tags__twitter-data1', 'url', 'meta_tags__article-author', 'domain', 'title', 'published__$date',\
'content', 'meta_tags__twitter-description']
prefix = 'train' if is_train else 'test'
feature_files = [open(os.path.join(path_to_data,'{}_{}.txt'.format(prefix, feat)),'w', encoding='utf-8')
for feat in features]
with open(os.path.join(PATH_TO_RAW_DATA, inp_filename),
encoding='utf-8') as inp_json_file:
for line in tqdm_notebook(inp_json_file):
for idx, features in enumerate(features):
json_data = read_json_line(line)
content = json_data['meta_tags']["twitter:data1"].replace('\n', ' ').replace('\r', ' ').split()[0]
feature_files[0].write(content + '\n')
content = json_data['url'].split('/')[-1].lower()
feature_files[1].write(content + '\n')
content = json_data['meta_tags']['article:author'].split('/')[-1].replace('@','').lower()
feature_files[2].write(content + '\n')
content = json_data['domain']
feature_files[3].write(content + '\n')
content = json_data['title'].replace('\n', ' ').replace('\r', ' ').lower()
feature_files[4].write(content + '\n')
content = json_data['published']['$date']
feature_files[5].write(content + '\n')
content = json_data['content'].replace('\n', ' ').replace('\r', ' ')
content = strip_tags(content).lower()
content = re.sub(r"[^a-zA-Z0-9]", " ", content)
feature_files[6].write(content + '\n')
content = json_data['meta_tags']["twitter:description"].replace('\n', ' ').replace('\r', ' ').lower()
feature_files[7].write(content + '\n')