Как добавить выходные данные в формате строки в pandas dataframe [duplicate]

Вызов статических методов в Java требует указания точного типа.

Обратите внимание, что этот подход не универсален для всех языков: например, вы можете переопределить методы класса в Objective-C, а какао-каркасы Apple хорошо используют этот механизм для настройки своих «фабричных» классов. Однако методы Java, C ++ и C # не поддерживают полиморфное поведение.

Теоретически разработчики Java могли позволить вам реализовать реализации метода интерфейса с помощью методов static в случае, если реализация не нуждается в доступе состояние из экземпляра. Но такое же поведение легко достичь с помощью тривиальной оболочки:

public class MyImplementation implements MyInterface {
    public MyImplementation(String name) {
    }
    @Override
    public MyInterface getInstance() { // static is not allowed here
        return getInstanceImpl();
    }
    public static getInstanceImpl() {
        return new MyImplementation(name)
    }
}

Компилятор Java мог бы сделать то же самое от вашего имени, но, увидев, что статический метод реализует метод экземпляра, является необычным и запутанным, поэтому я предполагаю, что разработчики Java решили отказаться от предоставления этого «волшебства».

477
задан Mel 31 August 2017 в 08:09
поделиться

18 ответов

Пример ответа @ Насера:

>>> import pandas as pd
>>> import numpy as np
>>> df = pd.DataFrame(columns=['lib', 'qty1', 'qty2'])
>>> for i in range(5):
>>>     df.loc[i] = [np.random.randint(-1,1) for n in range(3)]
>>>
>>> print(df)
    lib  qty1  qty2
0    0     0    -1
1   -1    -1     1
2    1    -1     1
3    0     0     0
4    1    -1    -1

[5 rows x 3 columns]
273
ответ дан cardamom 15 August 2018 в 23:06
поделиться
  • 1
    Подумайте о добавлении индекса для предопределения памяти (см. Мой ответ) – FooBar 23 July 2014 в 15:22
  • 2
    Не работает на pandas 0.11.0 – MaximG 21 October 2014 в 22:34
  • 3
    @MaximG: Я настоятельно рекомендую обновление. Текущая версия Pandas - 0.15.0. – fred 23 October 2014 в 20:17
  • 4
    .loc ссылается на индексный столбец, поэтому, если вы работаете с ранее существующим DataFrame с индексом, который не является непрерывной последовательностью целых чисел, начиная с 0 (как в вашем примере), .loc будет перезаписывать существующие строки , или вставить строки, или создать пробелы в вашем индексе. Более надежный (но не безупречный) подход для добавления существующего ненулевого фрейма данных будет: df.loc[df.index.max() + 1] = [randint(... или предустановить индекс, как предлагается @FooBar. – hobs 25 September 2015 в 23:21
  • 5
    @hobs: Я полностью согласен с вами. Спасибо за ваш вклад. Однако это отличается от предложенного в первоначальном вопросе. Если вы знаете, априорно, размер вашего фрейма данных, безусловно, быстрее выделять память. – fred 28 September 2015 в 13:18

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

import pandas as pd

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

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
6
ответ дан Brian Burns 15 August 2018 в 23:06
поделиться

Для эффективного добавления см. . Как добавить дополнительную строку в набор данных 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
51
ответ дан Community 15 August 2018 в 23:06
поделиться
  • 1
    Это должно быть проголосовано, самый краткий ответ для добавления одной строки – wiswit 27 May 2015 в 13:22
  • 2
    Вероятно, да. Но было бы лучше включить резюме ответа в ответ и использовать ссылки в качестве ссылки. – tashuhka 17 June 2015 в 19:26

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

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, разница в скорости становится еще больше:

Увеличение размера массива (12) и количества строк (500) делает разницу скорости более яркой: 313ms против 2.29s

63
ответ дан FooBar 15 August 2018 в 23:06
поделиться
  • 1
    Отличный ответ. Это должно быть нормой, так что пространство строк не должно выделяться постепенно. – ely 9 October 2014 в 19:32
  • 2
    Увеличение размера массива (12) и количества строк (500) делает разницу в скорости более яркой: 313мс против 2,29 – Tickon 2 April 2015 в 10:55
  • 3
    Если я знаю минимальное количество строк, стоит ли предварительно распределять память для большой части строк? – Cyrlop 20 February 2018 в 15:34

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

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
26
ответ дан hkyi 15 August 2018 в 23:06
поделиться
  • 1
    Я не знаю, является ли это очень эффективным, но это то, что мне нужно, потому что я уже создал фрейм данных и вам просто нужно добавить несколько строк. По сути, урок здесь (как в ответе @ ShikharDua) заключается в использовании словарей. – rocarvaj 15 January 2018 в 20:39

Создайте новую запись (кадр данных) и добавьте в 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])
5
ответ дан Jack Daniel 15 August 2018 в 23:06
поделиться
mycolumns = ['A', 'B']
df = pd.DataFrame(columns=mycolumns)
rows = [[1,2],[3,4],[5,6]]
for row in rows:
    df.loc[len(df)] = row
49
ответ дан Lydia 15 August 2018 в 23:06
поделиться
  • 1
    Эта! Я искал довольно долгое время, и это первое сообщение, которое действительно показывает, как назначать определенные значения строке! Бонусный вопрос: каков синтаксис пар столбцов / значений? Я думаю, что это должно быть что-то, использующее диктофон, но я не могу понять, что это правильно. – jhin 9 March 2016 в 01:00

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

226
ответ дан Michael WS 15 August 2018 в 23:06
поделиться
  • 1
    Привет, так что ответ для методов с помощью append () или concat (). У меня такая же проблема, но я все еще пытаюсь понять это. – notilas 20 August 2014 в 23:52
  • 2
    append не работает для меня в python3.4 – patapouf_ai 12 May 2016 в 22:17
  • 3
    Это правильный ответ, но это не очень хороший ответ good (почти ссылка). – jwg 18 May 2016 в 14:34
  • 4
    Я думаю, что ответ Фреда более верный. IIUC проблема с этим ответом заключается в том, что он без необходимости копирует весь DataFrame каждый раз, когда строка добавляется. Используя механизм .loc, которого можно избежать, особенно если вы осторожны. – Ken Williams 16 March 2017 в 17:03
  • 5
    Но если вы хотите использовать DataFrame.append(), вы должны убедиться, что данные вашей строки также являются DataFrame, а не списком. – StayFoolish 8 September 2017 в 12:46

Это было давно, но я столкнулся с такой же проблемой. И нашел здесь много интересных ответов. Поэтому я смутил, какой метод использовать.

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

СКОРОСТЬ ПРОИЗВОДИТЕЛЬНОСТИ

  1. Использование .append ( Ответ NPE )
  2. Использование ответа .loc ( fred и FooBar )
  3. Использование dict и создание DataFrame в конце ( Ответ ShikharDua ])

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

Adding    1000 rows  5000 rows   10000 rows
.append   1.04       4.84        9.56
.loc      1.16       5.59        11.50
dict      0.23       0.26        0.34

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


Код :

import pandas
import numpy
import time

numOfRows = 10000
startTime = time.perf_counter()
df1 = pandas.DataFrame(numpy.random.randint(100, size=(5,5)), columns=['A', 'B', 'C', 'D', 'E'])
for i in range( 1,numOfRows):
    df1 = df1.append( dict( (a,numpy.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))

startTime = time.perf_counter()
df2 = pandas.DataFrame(numpy.random.randint(100, size=(5,5)), columns=['A', 'B', 'C', 'D', 'E'])
for i in range( 1,numOfRows):
    df2.loc[df2.index.max()+1]  = numpy.random.randint(100, size=(1,5))[0]
print('Elapsed time: {:6.3f} seconds for {:d} rows'.format(time.perf_counter() - startTime, numOfRows))

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

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

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

6
ответ дан Mikhail_Sam 15 August 2018 в 23:06
поделиться

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

# 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
ответ дан qed 15 August 2018 в 23:06
поделиться

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

  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)               
210
ответ дан SergiyKolesnikov 15 August 2018 в 23:06
поделиться
  • 1
    Я перешел на это и для любой ситуации, когда я не могу получить все данные вперед. Разница в скорости удивительна. – fantabolous 13 August 2014 в 13:19
  • 2
    Разница в скорости действительно удивительна – baconwichsand 14 May 2015 в 19:57
  • 3
    Копирование из pandas docs: 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/… ) – thikonom 25 December 2015 в 23:01
  • 4
    Это отлично работает! За исключением случаев, когда я создал фрейм данных, имена колонок были в неправильном порядке ... – user5359531 9 August 2016 в 21:36
  • 5
    @ user5359531 Вы можете вручную указать столбцы, и порядок будет сохранен. pd.DataFrame (rows_list, columns = ['C1', 'C2', 'C3']) сделает трюк – Marcello Grechi Lins 27 January 2017 в 23:26

Это позаботится о добавлении элемента в пустой DataFrame. Проблема в том, что df.index.max () == nan для первого индекса:

df = pd.DataFrame(columns=['timeMS', 'accelX', 'accelY', 'accelZ', 'gyroX', 'gyroY', 'gyroZ'])

df.loc[0 if math.isnan(df.index.max()) else df.index.max() + 1] = [x for x in range(7)]
-1
ответ дан tomatom 15 August 2018 в 23:06
поделиться

Это не ответ на вопрос 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)
13
ответ дан user3250815 15 August 2018 в 23:06
поделиться
import pandas as pd 
t1=pd.DataFrame()
for i in range(len(the number of rows)):
    #add rows as columns
    t1[i]=list(rows)
t1=t1.transpose()
t1.columns=list(columns)
0
ответ дан Vicky 15 August 2018 в 23:06
поделиться

Сделайте это простым. Принимая список в качестве ввода, который будет добавлен в строку в кадре данных: -

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
ответ дан Vineet Jain 15 August 2018 в 23:06
поделиться

Вы можете добавить одну строку в качестве словаря, используя опцию 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
30
ответ дан W.P. McNeill 15 August 2018 в 23:06
поделиться
  • 1
    Вы можете также упомянуть, что f.append(<stuff>) создает новый объект, а не просто добавляет текущий объект на место, поэтому, если вы пытаетесь добавить к фреймворку данных в скрипте, вам нужно сказать f = f.append(<stuff>) – Blairg23 28 May 2016 в 03:57
  • 2
    есть ли способ сделать это на месте? – lol 8 November 2016 в 04:48
0
ответ дан Qinsi 5 September 2018 в 22:52
поделиться
0
ответ дан Shivam Agrawal 5 September 2018 в 22:52
поделиться
Другие вопросы по тегам:

Похожие вопросы: