Python-эффективный способ добавления строк в dataframe
отсюда вопрос и другие кажется, что не рекомендуется использовать concat
или append
для создания фрейма данных pandas, потому что он каждый раз перекопирует весь фрейм данных.
мой проект включает в себя получение небольшого количества данных каждые 30 секунд. Это может работать в течение 3-дневных выходных, поэтому кто-то может легко ожидать, что более 8000 строк будут созданы по одной строке за раз. Каков был бы наиболее эффективный способ добавления строк в этот фрейм данных?
3 ответов
вы можете добавить строки в фрейм данных на месте, используя loc
по несуществующему индексу. От панды документация:
In [119]: dfi
Out[119]:
A B C
0 0 1 0
1 2 3 2
2 4 5 4
In [120]: dfi.loc[3] = 5
In [121]: dfi
Out[121]:
A B C
0 0 1 0
1 2 3 2
2 4 5 4
3 5 5 5
как и ожидалось, используя loc
значительно быстрее, чем append
(около 14x):
import pandas as pd
df = pd.DataFrame({"A": [1,2,3], "B": [1,2,3], "C": [1,2,3]})
%%timeit
df2 = pd.DataFrame({"A": [4], "B": [4], "C": [4]})
df.append(df2)
# 1000 loops, best of 3: 1.61 ms per loop
%%timeit
df.loc[3] = 4
# 10000 loops, best of 3: 113 µs per loop
я использовал этот ответ df.loc[i] = [new_data]
предложение, но у меня есть > 500 000 строк, и это было очень медленно.
хотя приведенные ответы хороши для вопроса OP, я нашел его более эффективным, при работе с большим количеством строк спереди (вместо обмана, описанного OP), чтобы использовать csvwriter для добавления данных в объект CSV в памяти, а затем, наконец, использовать pandas.read_csv(csv)
для генерации желаемого вывода фрейма данных.
output = BytesIO()
csv_writer = writer(output)
for row in iterable_object:
csv_writer.writerow(row)
output.seek(0) # we need to get back to the start of the BytesIO
df = read_csv(output)
return df
это, для ~ 500,000 строк было 1000x быстрее и по мере роста количества строк улучшение скорости будет только увеличиваться (the df.loc[1] = [data]
будет намного медленнее сравнительно)
надеюсь, это поможет кому-то, кто нуждается в эффективности при работе с большим количеством строк, чем OP.
вам нужно разделить проблему на две части:
- принимать данные (собирая их) каждые 30 секунд эффективно.
- обработка данных после его сбора.
Если ваши данные критичны (то есть вы не можете позволить себе потерять их) - отправьте их в очередь, а затем прочитайте их из очереди пакетами.
очередь обеспечит надежное (гарантированное) прием и, что ваши данные не будут потеряны.
вы можете прочитать данные из очереди и дамп в базу данных.
теперь ваше приложение Python просто читает из базы данных и делает анализ с любым интервалом, который имеет смысл для приложения - возможно, вы хотите делать почасовые средние; в этом случае вы будете запускать свой скрипт каждый час, чтобы вытащить данные из БД и, возможно, записать результаты в другую базу данных / таблицу / файл.
нижняя строка-разделить сбор и анализ частей вашего приложения.