Python Эффективный способ синтаксического анализа строки до списка чисел с плавающей запятой из файла

В этом документе есть слово и десятки тысяч чисел с плавающей запятой на строку, я хочу преобразовать его в словарь со словом в качестве ключа и вектором со всеми числами с плавающей запятой. Я так и поступаю, но из-за размера файла (около 20 тыс. Строк каждая с примерно 10 тыс. Значений) процесс занимает слишком много времени. Я не мог найти более эффективный способ выполнения синтаксического анализа. Просто некоторые альтернативные способы, которые не гарантировали сокращение времени выполнения.

with open("googlenews.word2vec.300d.txt") as g_file:
  i = 0;
  #dict of words: [lots of floats]
  google_words = {}

  for line in g_file:
    google_words[line.split()[0]] = [float(line.split()[i]) for i in range(1, len(line.split()))]

Лучше определите «занять слишком много времени» - сколько времени это займет, и, если быть реалистом, сколько времени вы бы хотели, чтобы это длилось?

balmy 23.11.2018 18:12

Я бы, вероятно, позвонил line.split() один раз и назначил его переменной, вместо того, чтобы держать этот вызов в вашем понимании списка. Таким образом, вы можете специально перебирать его

C.Nivs 23.11.2018 18:12

То, что я собирался сказать ...

balmy 23.11.2018 18:13
Почему в Python есть оператор "pass"?
Почему в Python есть оператор "pass"?
Оператор pass в Python - это простая концепция, которую могут быстро освоить даже новички без опыта программирования.
Некоторые методы, о которых вы не знали, что они существуют в Python
Некоторые методы, о которых вы не знали, что они существуют в Python
Python - самый известный и самый простой в изучении язык в наши дни. Имея широкий спектр применения в области машинного обучения, Data Science,...
Основы Python Часть I
Основы Python Часть I
Вы когда-нибудь задумывались, почему в программах на Python вы видите приведенный ниже код?
LeetCode - 1579. Удаление максимального числа ребер для сохранения полной проходимости графа
LeetCode - 1579. Удаление максимального числа ребер для сохранения полной проходимости графа
Алиса и Боб имеют неориентированный граф из n узлов и трех типов ребер:
Оптимизация кода с помощью тернарного оператора Python
Оптимизация кода с помощью тернарного оператора Python
И последнее, что мы хотели бы показать вам, прежде чем двигаться дальше, это
Советы по эффективной веб-разработке с помощью Python
Советы по эффективной веб-разработке с помощью Python
Как веб-разработчик, Python может стать мощным инструментом для создания эффективных и масштабируемых веб-приложений.
1
3
274
3

Ответы 3

Только не звоните line.split() более одного раза.

with open("googlenews.word2vec.300d.txt") as g_file:
    i = 0;
    #dict of words: [lots of floats]
    google_words = {}

    for line in g_file:
        temp = line.split()
        google_words[temp[0]] = [float(temp[i]) for i in range(1, len(temp))]

Вот простой генератор такого файла:

s = "x"
for i in range (10000):
    s += " 1.2345"
print (s)

Первая версия требует времени. Версия с одним вызовом split - мгновенная.

В вашем решении вы дважды преобразуете медленный line.split() для каждого слова. Рассмотрим следующую модификацию:

with open("googlenews.word2vec.300d.txt") as g_file:
    i = 0;
    #dict of words: [lots of floats]
    google_words = {}

    for line in g_file:
        word, *numbers = line.split()
        google_words[word] = [float(number) for number in numbers]

Одна продвинутая концепция, которую я использовал здесь, - это «распаковка»: word, *numbers = line.split()

Python позволяет распаковывать повторяемые значения в несколько переменных:

a, b, c = [1, 2, 3]
# This is practically equivalent to
a = 1
b = 2
c = 3

* - это ярлык для «возьмите остатки, поместите их в list и назначьте список для имени»:

a, *rest = [1, 2, 3, 4]
# results in
a == 1
rest == [2, 3, 4]

Спасибо! Теперь это работает намного лучше. Один вопрос новичков, что делает * числа *? Это указатель, как в C, C++?

Victor Zuanazzi 23.11.2018 18:29

@VictorZuanazzi Нет, в python нет встроенных указателей;) Я объяснил этот синтаксический сахар в обновленном ответе.

Andrew Morozko 23.11.2018 18:42

Вы также можете использовать модуль csv, который должен быть более эффективным, чем то, что вы делаете.

Это было бы примерно так:

import csv

d = {}
with (open("huge_file_so_huge.txt", "r")) as g_file:
    for row in csv.reader(g_file, delimiter = " "):
        d[row[0]] = list(map(float, row[1:]))

Другие вопросы по теме