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.


вам нужно разделить проблему на две части:

  1. принимать данные (собирая их) каждые 30 секунд эффективно.
  2. обработка данных после его сбора.

Если ваши данные критичны (то есть вы не можете позволить себе потерять их) - отправьте их в очередь, а затем прочитайте их из очереди пакетами.

очередь обеспечит надежное (гарантированное) прием и, что ваши данные не будут потеряны.

вы можете прочитать данные из очереди и дамп в базу данных.

теперь ваше приложение Python просто читает из базы данных и делает анализ с любым интервалом, который имеет смысл для приложения - возможно, вы хотите делать почасовые средние; в этом случае вы будете запускать свой скрипт каждый час, чтобы вытащить данные из БД и, возможно, записать результаты в другую базу данных / таблицу / файл.

нижняя строка-разделить сбор и анализ частей вашего приложения.