Каков самый быстрый кортеж производительности для больших наборов данных в python?

Прямо сейчас, я в основном бегу через лист excel.

У меня около 20 имен, а затем у меня есть 50k общих значений, которые соответствуют одному из этих 20 имен, поэтому лист excel имеет длину 50k строк, столбец B показывает любое случайное значение, а столбец A показывает одно из 20 имен.

Я пытаюсь получить строку для каждого из имен, которые показывают все значения.

Name A: 123,244,123,523,123,5523,12505,142... etc etc. Name B: 123,244,123,523,123,5523,12505,142... etc etc. 

Прямо сейчас, я создал словарь, который проходит через лист excel, проверяет, все ли это имя в словаре, если оно есть, то оно делает

 strA = strA + "," + foundValue 

Затем он вставляет strA обратно в словарь для этого конкретного имени. Если имя не существует, оно создает ключ словаря и затем добавляет к нему это значение.

Теперь это сработало хорошо, но это было примерно 15-20 минут, и до сих пор это значение добавлено только к значениям 5 тыс., И со временем оно становится медленнее, и он продолжает работать.

Интересно, есть ли лучший способ сделать это или более быстрый способ сделать это. Я думал о создании новых словарей каждые 1 тыс. Значений, а затем объединить их все вместе в конце … но это будет 50 словарей, и это звучит сложно .. хотя, возможно, нет .. Я не уверен, может быть, он может работать лучше Таким образом, это, похоже, не работает.

Мне нужна строка, которая показывает каждое значение с запятой между каждым значением. Вот почему я делаю струнные вещи прямо сейчас.

5 Solutions collect form web for “Каков самый быстрый кортеж производительности для больших наборов данных в python?”

Есть ряд вещей, которые, вероятно, заставляют вашу программу работать медленно.

Конкатенация строк в python может быть крайне неэффективной при использовании с большими строками.

Строки в Python неизменяемы. Этот факт часто подкрадывается и кусает начинающих программистов Python на крупу. Неизменность дает некоторые преимущества и недостатки. В столбце плюс строки могут использоваться как ключи в словарях, а отдельные копии могут быть разделены между несколькими привязками переменных. (Python автоматически разделяет одно- и двухсимвольные строки.) В столбце «минус» вы не можете сказать что-то вроде «измените все« a »на« b »в любой заданной строке. Вместо этого вам нужно создать новую строку с требуемыми свойствами. Это постоянное копирование может привести к значительной неэффективности программ Python.

Учитывая, что каждая строка в вашем примере может содержать тысячи символов, каждый раз, когда вы выполняете конкатенацию, python должен копировать эту гигантскую строку в память для создания нового объекта.

Это будет намного более эффективно:

 strings = [] strings.append('string') strings.append('other_string') ... ','.join(strings) 

В вашем случае вместо каждого словарного ключа, хранящего массивную строку, он должен хранить список, и вы просто добавляете каждое соответствие в список, и только в самом конце вы будете выполнять конкатенацию строк с помощью str.join .

Кроме того, печать на stdout также известна медленно . Если вы печатаете на stdout на каждой итерации своего массивного 50 000 циклов элементов, каждая итерация удерживается небуферизованной записью в stdout. Рассмотрите только печать каждой nth итерации или, возможно, запись в файл (запись файлов обычно буферизуется), а затем удаление файла из другого терминала.

Этот ответ основан на ответе OP на мой комментарий. Я спросил, что он будет делать с диктоном, предполагая, что, возможно, ему не нужно строить его в первую очередь. @simon отвечает:

Я добавляю его в лист excel, поэтому я беру KEY, который является именем, и помещал его в A1, затем я принимаю значение VALUE, которое составляет 1345,345,135,346,3451,35 .. и т. д. и т. д., и помещаем его в A2 , то я делаю остальную часть своего программирования с этой информацией …… но мне нужны эти значения, разделенные запятыми и доступными внутри этого листа excel!

Таким образом, похоже, что дик не нужно строить в конце концов. Вот альтернатива: для каждого имени создайте файл и сохраните эти файлы в файле dict :

 files = {} name = 'John' # let's say if name not in files: files[name] = open(name, 'w') 

Затем, когда вы зацикливаетесь на 50k-строку excel, вы делаете что-то вроде этого (псевдокод):

 for row in 50k_rows: name, value_string = rows.split() # or whatever file = files[name] file.write(value_string + ',') # if already ends with ',', no need to add 

Поскольку ваш value_string уже разделен запятой, ваш файл будет csv-подобным, без каких-либо дополнительных настроек с вашей стороны (за исключением, может быть, вы хотите удалить последнюю запятую после того, как вы закончите). Затем, когда вам нужны значения, скажем, Джона, просто value = open('John').read() .

Теперь я никогда не работал с превосходными 50k-строками, но был бы очень удивлен, если бы это было не так быстро, как у вас в настоящее время. Наличие постоянных данных также (ну, может быть) плюс.


РЕДАКТИРОВАТЬ:

Выше – решение, ориентированное на память. Запись в файлы намного медленнее, чем добавление списков (но, вероятно, еще быстрее, чем воссоздание многих больших строк). Но если списки огромны (что кажется вероятным), и вы сталкиваетесь с проблемой памяти (не говорите, что хотите), вы можете попробовать файловый подход.

Альтернатива, похожая на списки в производительности (по крайней мере, для теста на игру, которую я пробовал), – это использовать StringIO :

 from io import StringIO # python 2: import StringIO import StringIO string_ios = {'John': StringIO()} # a dict to store StringIO objects for value in ['ab', 'cd', 'ef']: string_ios['John'].write(value + ',') print(string_ios['John'].getvalue()) 

Это выведет 'ab,cd,ef,'

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

Правильный способ – собрать в списках и присоединиться к концу, но если по какой-то причине вы хотите использовать строки, вы можете ускорить расширение строк. Вытащите строку из dict так, что есть только одна ссылка на нее, и, таким образом, оптимизация может ударить.

Демо-версия:

 >>> timeit('s = d.pop(k); s = s + "y"; d[k] = s', 'k = "x"; d = {k: ""}') 0.8417842664330237 >>> timeit('s = d[k]; s = s + "y"; d[k] = s', 'k = "x"; d = {k: ""}') 294.2475278390723 

В зависимости от того, как вы прочитали файл excel, но скажем, что строки читаются в виде разделенных разделителями кортежей или чего-то еще:

 d = {} for name, foundValue in line_tuples: try: d[name].append(foundValue) except KeyError: d[name] = [foundValue] d = {k: ",".join(v) for k, v in d.items()} 

Альтернативно, используя панды :

 import pandas as pd df = pd.read_excel("some_excel_file.xlsx") d = df.groupby("A")["B"].apply(lambda x: ",".join(x)).to_dict() 
  • Словарь Python не имеет всех назначенных ключей или элементов
  • Невозможно добавить значение в словарь python и записать в файл
  • суммирование элементов в вложенном словаре с разными ключами
  • Инициализировать список для переменной в словаре внутри цикла
  • формат вывода python для json
  • Понимание словаря Django Python, дающее синтаксическую ошибку
  • Получить подмножество словаря Python
  • python dict update diff
  •  
    Interesting Posts for Van-Lav
    Python - лучший язык программирования в мире.