Создайте фрейм данных Pandas, добавляя по одной строке за раз

1161

Я понимаю, что Pandas предназначен для загрузки полностью заполненного DataFrame, но мне нужно создать пустой DataFrame, а затем добавлять строки одну за другой . Как лучше всего это сделать?

Я успешно создал пустой DataFrame с помощью:

res = DataFrame(columns=('lib', 'qty1', 'qty2'))

Затем я могу добавить новую строку и заполнить поле:

res = res.set_value(len(res), 'qty1', 10.0)

Это работает, но кажется очень странным: - / (Не удается добавить строковое значение.)

Как я могу добавить новую строку в мой DataFrame (с другим типом столбцов)?

7
  • 78
    Обратите внимание, что это очень неэффективный способ создания большого DataFrame; при добавлении строки необходимо создавать новые массивы (копируя существующие данные). 23 мая '12 в 13:46
  • 6
    @WesMcKinney: Спасибо, это действительно полезно знать. Очень быстро добавлять столбцы в огромные таблицы?
    max
    28 авг.
  • 5
    Если это слишком неэффективно для вас, вы можете предварительно выделить дополнительную строку, а затем обновить ее. 19 апр.
  • 19
    Эй, ты ... да, ты ... Я понимаю, что ты задумал ... ты хочешь запустить это внутри цикла и итеративно добавлять строки в пустой DataFrame, не так ли ... ну, не надо ' т!
    cs95
    13 июл.
  • 2
    Я могу понять, что это может быть в целом неправильным, но как насчет обработки в реальном времени? Скажем, у меня есть данные, которые поступают каждую секунду, и у меня есть поток, который просто хочет заполнить фрейм данных, и у меня есть другой поток, основанный на четности, который идет и смотрит на фрейм данных? Я считаю этот вариант использования допустимым, и где это решение применимо к 20 ноя '20 в 17:24
785

Вы можете использовать df.loc[i], где строка с индексом iбудет тем, что вы указали в фрейме данных.

>>> import pandas as pd
>>> from numpy.random import randint

>>> df = pd.DataFrame(columns=['lib', 'qty1', 'qty2'])
>>> for i in range(5):
>>>     df.loc[i] = ['name' + str(i)] + list(randint(10, size=2))

>>> df
     lib qty1 qty2
0  name0    3    3
1  name1    2    4
2  name2    2    8
3  name3    2    1
4  name4    9    6
7
  • 34
    Рассмотрите возможность добавления индекса для предварительного выделения памяти (см. Мой ответ)
    FooBar
    23 июл.
  • 56
    .locссылается на столбец индекса, поэтому, если вы работаете с уже существующим DataFrame с индексом, который не является непрерывной последовательностью целых чисел, начинающихся с 0 (как в вашем примере), .locбудет перезаписывать существующие строки или вставлять строки, или создавать пробелы в вашем индексе. Более надежным (но не защищенным от ошибок) подходом к добавлению существующего df.loc[df.index.max() + 1] = [randint(...фрейма данных ненулевой длины было бы следующее: или предварительное заполнение индекса, как предлагает @FooBar.
    hobs
    25 сен.
  • 5
    @hobs df.index.max()- это nanкогда DataFrame пуст.
    flow2k
    24 апр '19 в 1:30
  • 2
    @ flow2k хороший улов! Единственное решение, о котором я могу думать, - это попытка принять (только при вставке первой строки) с вызовом конструктора pd.DataFrame (). Вы знаете способы получше?
    hobs
    24 апр '19 в 21:31
  • 12
    @hobs Одно из решений, которое я придумал, - использовать тернарный оператор: df.loc[0 if pd.isnull(df.index.max()) else df.index.max() + 1]
    flow2k
    25 апр '19 в 21:17
653

Если вы можете получить все данные для фрейма данных заранее, существует гораздо более быстрый подход, чем добавление во фрейм данных:

  1. Создайте список словарей, в котором каждый словарь соответствует строке входных данных.
  2. Создайте фрейм данных из этого списка.

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

rows_list = []
for row in input_rows:

        dict1 = {}
        # get input row in dictionary format
        # key = col_name
        dict1.update(blah..) 

        rows_list.append(dict1)

df = pd.DataFrame(rows_list)               
16
  • 63
    Я перешел к этому и в любой ситуации, когда я не могу получить все данные заранее. Разница в скорости поразительная. 13 авг.
  • 63
    Копирование из документов pandas: It is worth noting however, that concat (and therefore append) makes a full copy of the data, and that constantly reusing this function can create a significant performance hit. If you need to use the operation over several datasets, use a list comprehension.( pandas.pydata.org/pandas-docs/stable/… ) 25 дек.
  • 7
    Это прекрасно работает! За исключением того, что я создал фрейм данных, имена столбцов были в неправильном порядке ... 9 авг.
  • 5
    @ user5359531 В этом случае вы можете использовать заказанный dict 10 авг.
  • 25
    @ user5359531 Вы можете указать столбцы вручную, и порядок будет сохранен. pd.DataFrame (rows_list, columns = ['C1', 'C2', 'C3']) поможет 27 янв.
321

Вы можете использовать pandas.concat()или DataFrame.append(). Дополнительные сведения и примеры см. В разделе Слияние, присоединение и объединение .

4
  • 7
    Привет, так каков ответ на методы, использующие append () или concat (). У меня та же проблема, но я все еще пытаюсь ее решить.
    notilas
    20 авг.
  • 140
    Это правильный ответ, но это не очень хороший ответ (почти только ссылка).
    jwg
    18 мая '16 в 14:34
  • 5
    Я думаю, что ответ @fred более правильный. IIUC проблема с этим ответом заключается в том, что он без необходимости копирует весь DataFrame каждый раз, когда добавляется строка. Использование .locмеханизма, которого можно избежать, особенно если вы будете осторожны. 16 марта '17 в 16: 032017-03-16 16:03
  • 7
    Но если вы хотите использовать DataFrame.append(), вы должны убедиться, что данные вашей строки также являются DataFrame, а не списком. 8 сен '17 в 12:46
311

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

Представление

  1. Использование .append ( ответ NPE )
  2. Использование .loc ( ответ Фреда )
  3. Использование .loc с предварительным выделением (ответ FooBar )
  4. Используя dict и создайте DataFrame в конце ( ответ ShikharDua )

Результаты выполнения (в секундах):

Подход 1000 рядов 5000 рядов 10 000 строк
.append 0,69 3,39 6,78
.loc без prealloc 0,74 3,90 8,35
.loc с prealloc 0,24 2,58 8,70
диктовать 0,012 0,046 0,084

Так что прибавление через словарь использую для себя.


Код:

import pandas as pd
import numpy as np
import time

del df1, df2, df3, df4
numOfRows = 1000
# append
startTime = time.perf_counter()
df1 = pd.DataFrame(np.random.randint(100, size=(5,5)), columns=['A', 'B', 'C', 'D', 'E'])
for i in range( 1,numOfRows-4):
    df1 = df1.append( dict( (a,np.random.randint(100)) for a in ['A','B','C','D','E']), ignore_index=True)
print('Elapsed time: {:6.3f} seconds for {:d} rows'.format(time.perf_counter() - startTime, numOfRows))
print(df1.shape)

# .loc w/o prealloc
startTime = time.perf_counter()
df2 = pd.DataFrame(np.random.randint(100, size=(5,5)), columns=['A', 'B', 'C', 'D', 'E'])
for i in range( 1,numOfRows):
    df2.loc[i]  = np.random.randint(100, size=(1,5))[0]
print('Elapsed time: {:6.3f} seconds for {:d} rows'.format(time.perf_counter() - startTime, numOfRows))
print(df2.shape)

# .loc with prealloc
df3 = pd.DataFrame(index=np.arange(0, numOfRows), columns=['A', 'B', 'C', 'D', 'E'] )
startTime = time.perf_counter()
for i in range( 1,numOfRows):
    df3.loc[i]  = np.random.randint(100, size=(1,5))[0]
print('Elapsed time: {:6.3f} seconds for {:d} rows'.format(time.perf_counter() - startTime, numOfRows))
print(df3.shape)

# dict
startTime = time.perf_counter()
row_list = []
for i in range (0,5):
    row_list.append(dict( (a,np.random.randint(100)) for a in ['A','B','C','D','E']))
for i in range( 1,numOfRows-4):
    dict1 = dict( (a,np.random.randint(100)) for a in ['A','B','C','D','E'])
    row_list.append(dict1)

df4 = pd.DataFrame(row_list, columns=['A','B','C','D','E'])
print('Elapsed time: {:6.3f} seconds for {:d} rows'.format(time.perf_counter() - startTime, numOfRows))
print(df4.shape)

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

13
  • 4
    Использование df2.index.max()for .locбез необходимости увеличивает вычислительную сложность. Подойдет простое df2.loc[i] = .... Для меня это уменьшило время с 10 до 8,64 с. 23 янв.
  • Пожалуйста, удалите мое имя из списка, поскольку вы не следуете моему подходу в своем тесте: вы не распределяете память заранее, предоставляя индекс подходящего размера.
    FooBar
    29 июля '19 в 21: 272019-07-29 18:27
  • @FooBar Привет! Рад, что вы как автор увидели мой ответ :) вы правы, я упустил этот важный момент. Я предпочитаю добавить еще одну строку для моей таблицы результатов, так как ваш подход показывает другой результат! 30 июл.
  • 1
    @Mikhail_Sam И напоследок, диктаторский подход, каково обоснование использования двух циклов, for i in range (0,5):и for i in range( 1,numOfRows-4):?
    flow2k
    29 сен '19 в 9:03
  • 1
    Просто хотел выкинуть еще один комментарий о том, почему Dict to Pandas DataFrame - лучший способ. В моих экспериментах с набором данных, который имеет несколько разных типов данных в таблице, использование методов добавления Pandas разрушает типизацию, тогда как использование Dict и создание только одного DataFrame из него ОДИН РАЗ, кажется, сохраняет исходные типы данных нетронутыми. 4 дек '19 в 14:23
172

НИКОГДА не увеличивайте DataFrame!

Да, люди уже объяснили, что вам НИКОГДА не следует увеличивать DataFrame, и что вы должны добавить свои данные в список и преобразовать его в DataFrame один раз в конце. Но ты понимаешь почему?

Вот самые важные причины, взятые из моего поста здесь .

  1. Всегда дешевле / быстрее добавить в список и создать DataFrame за один раз.
  2. Списки занимают меньше памяти и представляют собой гораздо более легкую структуру данных для работы, добавления и удаления.
  3. dtypesавтоматически выводятся для ваших данных. С другой стороны, создание пустого фрейма из NaN приведет к их автоматическому созданию object, что плохо.
  4. Индекс создается для вас автоматически, и вам не нужно заботиться о присвоении правильного индекса добавляемой строке.

Это правильный путь ™ для накопления ваших данных

data = []
for a, b, c in some_function_that_yields_data():
    data.append([a, b, c])

df = pd.DataFrame(data, columns=['A', 'B', 'C'])

Эти варианты ужасны

  1. appendили concatвнутри цикла

    appendи concatне плохи по своей сути в изоляции . Проблема начинается, когда вы итеративно вызываете их внутри цикла - это приводит к квадратичному использованию памяти.

    # Creates empty DataFrame and appends
    df = pd.DataFrame(columns=['A', 'B', 'C'])
    for a, b, c in some_function_that_yields_data():
        df = df.append({'A': i, 'B': b, 'C': c}, ignore_index=True)  
        # This is equally bad:
        # df = pd.concat(
        #       [df, pd.Series({'A': i, 'B': b, 'C': c})], 
        #       ignore_index=True)
    
  2. Пустой фрейм данных из NaN

    Никогда не создавайте DataFrame из NaN, поскольку столбцы инициализируются с помощью object(медленный, не векторизуемый dtype).

    # Creates DataFrame of NaNs and overwrites values.
    df = pd.DataFrame(columns=['A', 'B', 'C'], index=range(5))
    for a, b, c in some_function_that_yields_data():
        df.loc[len(df)] = [a, b, c]
    

Доказательство в пудинге

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

введите описание изображения здесь

Код эталонного тестирования для справки.


Подобные сообщения напоминают мне, почему я являюсь частью этого сообщества. Люди понимают важность обучения людей получению правильного ответа с помощью правильного кода, а не правильного ответа с помощью неправильного кода. Теперь вы можете утверждать , что это не является проблемой для использования locили appendесли вы только добавить одну строку в вашем DataFrame. Однако люди часто обращаются к этому вопросу, чтобы добавить больше, чем просто одну строку - часто требуется итеративное добавление строки внутри цикла с использованием данных, поступающих от функции (см. Связанный вопрос ). В этом случае важно понимать, что итеративное наращивание DataFrame - не лучшая идея.

9
  • 5
    Справедливо. Есть ли какое-нибудь решение, если вам нужен (или вы хотите) фрейм данных, но все ваши образцы действительно приходят один за другим? (Обычно онлайн-обучение или активное обучение) 8 сен '20 в 15:52
  • Это не влияет на тот случай, когда фрейм данных нужен после каждого append (). В этом случае фрейм данных все равно копируется, поэтому метод df.loc работает быстрее. 17 сен '20 в 10:45
  • @DevAggarwal неверно, loc также каждый раз создает копию. Пожалуйста, посмотрите график времени в моем ответе. Append и loc_append одинаково плохи. Я также поделился своим кодом и процессом, так что вы можете убедиться в этом сами.
    cs95
    17 сен '20 в 16:36
  • Аплогии должны были быть яснее. Пожалуйста, создайте фрейм данных из промежуточного списка внутри цикла for, здесь - gist.github.com/Coldsp33d/… 17 сен '20 в 17:10
  • 1
    хороший ответ @ cs95! 5 янв в 12:44
123

Если вы знаете количество записей заранее, вам следует предварительно выделить пространство, также указав индекс (взяв пример данных из другого ответа):

import pandas as pd
import numpy as np
# we know we're gonna have 5 rows of data
numberOfRows = 5
# create dataframe
df = pd.DataFrame(index=np.arange(0, numberOfRows), columns=('lib', 'qty1', 'qty2') )

# now fill it up row by row
for x in np.arange(0, numberOfRows):
    #loc or iloc both work here since the index is natural numbers
    df.loc[x] = [np.random.randint(-1,1) for n in range(3)]
In[23]: df
Out[23]: 
   lib  qty1  qty2
0   -1    -1    -1
1    0     0     0
2   -1     0    -1
3    0    -1     0
4   -1     0     0

Сравнение скорости

In[30]: %timeit tryThis() # function wrapper for this answer
In[31]: %timeit tryOther() # function wrapper without index (see, for example, @fred)
1000 loops, best of 3: 1.23 ms per loop
100 loops, best of 3: 2.31 ms per loop

И - как из комментариев - при размере 6000 разница в скорости становится еще больше:

Increasing the size of the array (12) and the number of rows (500) makes the speed difference more striking: 313ms vs 2.29s

2
  • 4
    Отличный ответ. Это должно быть нормой, чтобы пространство строки не распределялось постепенно.
    ely
    9 окт.
  • 9
    Увеличение размера массива (12) и количества строк (500) делает разницу в скорости более заметной: 313 мс против 2,29 с.
    Tickon
    2 апр '15 в 10:55
91
mycolumns = ['A', 'B']
df = pd.DataFrame(columns=mycolumns)
rows = [[1,2],[3,4],[5,6]]
for row in rows:
    df.loc[len(df)] = row
2
  • 3
    Этот! Я долго искал, и это первый пост, который действительно показывает, как присваивать определенные значения строке! Дополнительный вопрос: каков синтаксис для пар "имя-столбец / значение"? Я предполагаю, что это должно быть что-то, использующее диктатор, но я не могу понять это правильно.
    jhin
    9 марта '16 в 0:00
  • 7
    это неэффективно, поскольку фактически копирует весь DataFrame при его расширении. 25 июл.
78

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

>>> f = pandas.DataFrame(data = {'Animal':['cow','horse'], 'Color':['blue', 'red']})
>>> f
  Animal Color
0    cow  blue
1  horse   red
>>> f.append({'Animal':'mouse', 'Color':'black'}, ignore_index=True)
  Animal  Color
0    cow   blue
1  horse    red
2  mouse  black
4
  • 46
    Вы также можете упомянуть, что f.append(<stuff>)создается новый объект, а не просто добавляется к текущему объекту на месте, поэтому, если вы пытаетесь добавить к кадру данных в скрипте, вам нужно сказатьf = f.append(<stuff>) 28 мая '16 в 3:57
  • 2
    есть ли способ сделать это на месте?
    lol
    8 ноя '16 в 3:48
  • @хах нет. см. github.com/pandas-dev/pandas/issues/2801 - базовые массивы не могут быть расширены, поэтому их нужно скопировать. 25 июл.
  • 1
    Я предпочитаю этот метод, потому что он очень похож на SQL (семантически не зависит от индексов), и я использую его, когда это возможно.
    Gene M
    31 июля '20 в 21:45
75

Для эффективного добавления см. Раздел « Как добавить дополнительную строку в фрейм данных pandas» и « Настройка с увеличением» .

Добавьте строки loc/ixв несуществующие ключевые данные индекса. Например:

In [1]: se = pd.Series([1,2,3])

In [2]: se
Out[2]:
0    1
1    2
2    3
dtype: int64

In [3]: se[5] = 5.

In [4]: se
Out[4]:
0    1.0
1    2.0
2    3.0
5    5.0
dtype: float64

Или:

In [1]: dfi = pd.DataFrame(np.arange(6).reshape(3,2),
   .....:                 columns=['A','B'])
   .....:

In [2]: dfi
Out[2]:
   A  B
0  0  1
1  2  3
2  4  5

In [3]: dfi.loc[:,'C'] = dfi.loc[:,'A']

In [4]: dfi
Out[4]:
   A  B  C
0  0  1  0
1  2  3  2
2  4  5  4
In [5]: dfi.loc[3] = 5

In [6]: dfi
Out[6]:
   A  B  C
0  0  1  0
1  2  3  2
2  4  5  4
3  5  5  5
3
  • 1
    Пользователи просили орудие (добавить новую строку). Здесь мы видим, как добавить строку в определенный индекс или добавить столбец. 21 фев '19 в 15:38
  • 1
    любые тесты того, как это работает по сравнению с методом dict 06 марта '19 в 17:15
  • это неэффективно, поскольку фактически копирует весь DataFrame. 25 июл.
47

Ради питонического пути:

res = pd.DataFrame(columns=('lib', 'qty1', 'qty2'))
res = res.append([{'qty1':10.0}], ignore_index=True)
print(res.head())

   lib  qty1  qty2
0  NaN  10.0   NaN
0
33

Вы также можете создать список списков и преобразовать его в фреймворк данных -

import pandas as pd

columns = ['i','double','square']
rows = []

for i in range(6):
    row = [i, i*2, i*i]
    rows.append(row)

df = pd.DataFrame(rows, columns=columns)

давая

    i   double  square
0   0   0   0
1   1   2   1
2   2   4   4
3   3   6   9
4   4   8   16
5   5   10  25
16

Я придумал простой и приятный способ:

>>> df
     A  B  C
one  1  2  3
>>> df.loc["two"] = [4,5,6]
>>> df
     A  B  C
one  1  2  3
two  4  5  6

Обратите внимание на оговорку с производительностью, как указано в комментариях.

1
  • 2
    Обратите внимание, что это скопирует весь DataFrame под капотом. Базовые массивы не могут быть расширены, поэтому их нужно скопировать. 25 июл.
14

Это не ответ на вопрос OP, а игрушечный пример, иллюстрирующий ответ ShikharDua, который я нашел очень полезным.

Хотя этот фрагмент тривиален, в реальных данных у меня было 1000 строк и много столбцов, и я хотел иметь возможность группировать по разным столбцам, а затем выполнять статистику ниже для более чем одного целевого столбца. Поэтому наличие надежного метода построения фрейма данных по одной строке за раз было большим удобством. Спасибо ShikharDua!

import pandas as pd

BaseData = pd.DataFrame({ 'Customer' : ['Acme','Mega','Acme','Acme','Mega','Acme'],
                          'Territory'  : ['West','East','South','West','East','South'],
                          'Product'  : ['Econ','Luxe','Econ','Std','Std','Econ']})
BaseData

columns = ['Customer','Num Unique Products', 'List Unique Products']

rows_list=[]
for name, group in BaseData.groupby('Customer'):
    RecordtoAdd={} #initialise an empty dict
    RecordtoAdd.update({'Customer' : name}) #
    RecordtoAdd.update({'Num Unique Products' : len(pd.unique(group['Product']))})
    RecordtoAdd.update({'List Unique Products' : pd.unique(group['Product'])})

    rows_list.append(RecordtoAdd)

AnalysedData = pd.DataFrame(rows_list)

print('Base Data : \n',BaseData,'\n\n Analysed Data : \n',AnalysedData)
10

Вы можете использовать объект-генератор для создания Dataframe, который будет более эффективно использовать память по сравнению со списком.

num = 10

# Generator function to generate generator object
def numgen_func(num):
    for i in range(num):
        yield ('name_{}'.format(i), (i*i), (i*i*i))

# Generator expression to generate generator object (Only once data get populated, can not be re used)
numgen_expression = (('name_{}'.format(i), (i*i), (i*i*i)) for i in range(num) )

df = pd.DataFrame(data=numgen_func(num), columns=('lib', 'qty1', 'qty2'))

Чтобы добавить необработанные данные в существующий DataFrame, вы можете использовать метод добавления.

df = df.append([{ 'lib': "name_20", 'qty1': 20, 'qty2': 400  }])
8

Создайте новую запись (фрейм данных) и добавьте в old_data_frame .

Передайте список значений и соответствующие имена столбцов, чтобы создать new_record (data_frame):

new_record = pd.DataFrame([[0, 'abcd', 0, 1, 123]], columns=['a', 'b', 'c', 'd', 'e'])

old_data_frame = pd.concat([old_data_frame, new_record])
7

Вот способ добавить / добавить строку в пандах DataFrame:

def add_row(df, row):
    df.loc[-1] = row
    df.index = df.index + 1
    return df.sort_index()

add_row(df, [1,2,3])

Его можно использовать для вставки / добавления строки в пустой или заполненный фрейм данных Pandas.

1
  • 1
    это добавление с индексом в порядке убывания 13 окт.
7

Вместо списка словарей, как в ответе ShikharDua , мы также можем представить нашу таблицу как словарь списков , где каждый список хранит один столбец в порядке строк, если мы заранее знаем наши столбцы. В конце мы создаем наш DataFrame один раз.

Для c столбцов и n строк используется один словарь и c списков, а не один список и n словарей. Метод list-of-dictionaries содержит каждый словарь, в котором хранятся все ключи, и требует создания нового словаря для каждой строки. Здесь мы только добавляем в списки, что является постоянным временем и теоретически очень быстро.

# Current data
data = {"Animal":["cow", "horse"], "Color":["blue", "red"]}

# Adding a new row (be careful to ensure every column gets another value)
data["Animal"].append("mouse")
data["Color"].append("black")

# At the end, construct our DataFrame
df = pd.DataFrame(data)
#   Animal  Color
# 0    cow   blue
# 1  horse    red
# 2  mouse  black
5

Если вы всегда хотите добавить новую строку в конце, используйте это:

df.loc[len(df)] = ['name5', 9, 0]
4

Если вы хотите добавить строку в конце, добавьте ее в виде списка:

valuestoappend = [va1, val2, val3]
res = res.append(pd.Series(valuestoappend, index = ['lib', 'qty1', 'qty2']), ignore_index = True)
3

Другой способ сделать это (вероятно, не очень производительный):

# add a row
def add_row(df, row):
    colnames = list(df.columns)
    ncol = len(colnames)
    assert ncol == len(row), "Length of row must be the same as width of DataFrame: %s" % row
    return df.append(pd.DataFrame([row], columns=colnames))

Вы также можете улучшить класс DataFrame следующим образом:

import pandas as pd
def add_row(self, row):
    self.loc[len(self.index)] = row
pd.DataFrame.add_row = add_row
3

Все, что вам нужно, это loc[df.shape[0]]илиloc[len(df)]


# Assuming your df has 4 columns (str, int, str, bool)
df.loc[df.shape[0]] = ['col1Value', 100, 'col3Value', False] 

или

df.loc[len(df)] = ['col1Value', 100, 'col3Value', False] 
2
initial_data = {'lib': np.array([1,2,3,4]), 'qty1': [1,2,3,4], 'qty2': [1,2,3,4]}

df = pd.DataFrame(initial_data)

df

lib    qty1    qty2
0    1    1    1
1    2    2    2
2    3    3    3
3    4    4    4

val_1 = [10]
val_2 = [14]
val_3 = [20]

df.append(pd.DataFrame({'lib': val_1, 'qty1': val_2, 'qty2': val_3}))

lib    qty1    qty2
0    1    1    1
1    2    2    2
2    3    3    3
3    4    4    4
0    10    14    20

Вы можете использовать цикл for для перебора значений или можете добавлять массивы значений.

val_1 = [10, 11, 12, 13]
val_2 = [14, 15, 16, 17]
val_3 = [20, 21, 22, 43]

df.append(pd.DataFrame({'lib': val_1, 'qty1': val_2, 'qty2': val_3}))

lib    qty1    qty2
0    1    1    1
1    2    2    2
2    3    3    3
3    4    4    4
0    10    14    20
1    11    15    21
2    12    16    22
3    13    17    43
1
  • Пояснение к первой части было бы в порядке. И почему в примере кода нет цикла for, когда о нем говорят? Вы можете прояснить это? Пожалуйста, ответьте, отредактировав свой ответ , а не здесь, в комментариях ( без «Изменить:», «Обновить:» и т. Д. - ответ должен выглядеть так, как если бы он был написан сегодня). 14 июл в 10:14
1

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

import pandas as pd
res = pd.DataFrame(columns=('lib', 'qty1', 'qty2'))
for i in range(5):
    res_list = list(map(int, input().split()))
    res = res.append(pd.Series(res_list, index=['lib', 'qty1', 'qty2']), ignore_index=True)
0
0

Если у вас есть фрейм данных dfи вы хотите добавить список new_list в качестве новой строки df, вы можете просто сделать:

df.loc[len(df)] = new_list

Если вы хотите добавить новый фрейм new_df данных под фрейм данных df, вы можете использовать:

df.append(new_df)
0

Мы часто видим конструкцию, df.loc[subscript] = …которая назначается одной строке DataFrame. Михаил_Сам опубликовал тесты, содержащие, среди прочего, эту конструкцию, а также метод, использующий dict и создающий в конце DataFrame . Он обнаружил, что последний на сегодняшний день был самым быстрым.

Но если мы заменим df3.loc[i] = …(с предварительно выделенным DataFrame) в его коде на df3.values[i] = …, результат значительно изменится, поскольку этот метод работает аналогично тому, который использует dict. Поэтому мы должны чаще принимать во внимание использование df.values[subscript] = …. Однако обратите внимание, что для этого .valuesиспользуется нижний индекс, начинающийся с нуля, который может отличаться от DataFrame.index.

1
0

pandas.DataFrame.append

DataFrame.append (self, other, ignore_index = False, verify_integrity = False, sort = False) → 'DataFrame'

Код

df = pd.DataFrame([[1, 2], [3, 4]], columns=list('AB'))
df2 = pd.DataFrame([[5, 6], [7, 8]], columns=list('AB'))
df.append(df2)

Если для ignore_index установлено значение True:

df.append(df2, ignore_index=True)
1
  • Непонятно, почему первые две строки не являются буквальным кодом. Краткость - это хорошо, но можете ли вы уточнить свой ответ , например, добавив вспомогательный текст? Но без «Изменить:», «Обновить:» и т. Д. Ответ должен выглядеть так, как если бы он был написан сегодня. 14 июл в 10:05
0

Для этого вы можете объединить два DataFrames. Я в основном столкнулся с этой проблемой, чтобы добавить новую строку в существующий DataFrame с символьным индексом (не числовым).

Итак, я ввожу данные для новой строки в duct () и индексирую их в списке.

new_dict = {put input for new row here}
new_list = [put your index here]

new_df = pd.DataFrame(data=new_dict, index=new_list)

df = pd.concat([existing_df, new_df])
0

Если все данные в вашем Dataframe имеют один и тот же dtype, вы можете использовать массив NumPy. Вы можете записывать строки прямо в предопределенный массив и преобразовывать его в конце в фрейм данных. Кажется, это даже быстрее, чем преобразование списка диктовок.

import pandas as pd
import numpy as np
from string import ascii_uppercase

startTime = time.perf_counter()
numcols, numrows = 5, 10000
npdf = np.ones((numrows, numcols))
for row in range(numrows):
    npdf[row, 0:] = np.random.randint(0, 100, (1, numcols))
df5 = pd.DataFrame(npdf, columns=list(ascii_uppercase[:numcols]))
print('Elapsed time: {:6.3f} seconds for {:d} rows'.format(time.perf_counter() - startTime, numOfRows))
print(df5.shape)
1
  • Re: «Кажется, это даже быстрее» : можете ли вы дать количественную оценку ( отредактировав (изменив) свой ответ )? О каком порядке идет речь? На 10% быстрее? На 100% быстрее? В 10 раз быстрее? В 1000000 раз быстрее? В каком масштабе (может быть квадратичным / экспоненциальным)? 14 июл в 10:25
0

Этот фрагмент кода использует список словарей для обновления фрейма данных. Он дополняет ответы ShikharDua и Mikhail_Sam .

import pandas as pd
colour = ["red", "big", "tasty"]
fruits = ["apple", "banana", "cherry"]
dict1={}
feat_list=[]
for x in colour:
    for y in fruits:
#         print(x, y)
        dict1 = dict([('x',x),('y',y)])
#         print(f'dict 1 {dict1}')
        feat_list.append(dict1)
#         print(f'feat_list {feat_list}')
feat_df=pd.DataFrame(feat_list)
feat_df.to_csv('feat1.csv')
-1

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

Эта идея заставляет меня написать приведенный ниже код.

df2 = df.to_dict()
values = ["s_101", "hyderabad", 10, 20, 16, 13, 15, 12, 12, 13, 25, 26, 25, 27, "good", "bad"] # This is the total row that we are going to add
i = 0
for x in df.columns:   # Here df.columns gives us the main dictionary key
    df2[x][101] = values[i]   # Here the 101 is our index number. It is also the key of the sub dictionary
    i += 1