it-swarm.com.de

Fügen Sie pandas DataFrame eine Zeile hinzu

Ich verstehe, dass pandas so konzipiert ist, dass es vollständig ausgefüllte DataFrame lädt, aber ich muss einen leeren DataFrame erstellen und dann nacheinander Zeilen hinzufügen. Wie geht das am besten?

Ich habe erfolgreich einen leeren DataFrame erstellt mit:

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

Dann kann ich eine neue Zeile hinzufügen und ein Feld füllen mit:

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

Es funktioniert, scheint aber sehr seltsam: -/(es schlägt fehl, einen String-Wert hinzuzufügen)

Wie kann ich meinem DataFrame eine neue Zeile hinzufügen (mit unterschiedlichen Spaltentypen)?

672
PhE
>>> 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
433
fred

Wenn Sie alle Daten für den Datenrahmen im Voraus abrufen können, gibt es einen viel schnelleren Ansatz als das Anhängen an einen Datenrahmen:

  1. Erstellen Sie eine Liste von Wörterbüchern, in denen jedes Wörterbuch einer Eingabedatenzeile entspricht.
  2. Erstellen Sie einen Datenrahmen aus dieser Liste.

Ich hatte eine ähnliche Aufgabe, für die das Anhängen an einen Datenrahmen zeilenweise 30 Minuten dauerte und das Erstellen eines Datenrahmens aus einer Liste von Wörterbüchern innerhalb von Sekunden abgeschlossen war.

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)               
351
ShikharDua

Sie können pandas.concat() oder DataFrame.append() verwenden. Einzelheiten und Beispiele finden Sie unter Zusammenführen, Verbinden und Verketten .

259
NPE

Wenn Sie die Anzahl der Einträge ex ante kennen, sollten Sie den Speicherplatz vorbelegen, indem Sie auch den Index angeben (das Datenbeispiel stammt aus einer anderen Antwort):

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

Geschwindigkeitsvergleich

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

Und - wie aus den Kommentaren hervorgeht - mit einer Größe von 6000 wird der Geschwindigkeitsunterschied noch größer:

Durch Erhöhen der Größe des Arrays (12) und der Anzahl der Zeilen (500) wird der Geschwindigkeitsunterschied deutlicher: 313 ms gegenüber 2,29 s

91
FooBar

Es ist lange her, aber ich hatte auch das gleiche Problem. Und hier viele interessante Antworten gefunden. Also war ich verwirrt, welche Methode ich anwenden sollte.

Im Fall des Hinzufügens vieler Zeilen zum Datenrahmen interessierte ich mich für die Geschwindigkeitsleistung . Also habe ich 4 gängige Methoden ausprobiert und deren Geschwindigkeit überprüft.

AKTUALISIERT IM JAHR 2019 mit neuen Versionen von Paketen. Auch aktualisiert nach @ FooBar Kommentar

GESCHWINDIGKEITSLEISTUNG

  1. Verwenden von .append ( NPEs Antwort )
  2. Verwenden von .loc ( freds Antwort )
  3. Verwenden von .loc mit Vorbelegung ( Antwort von FooBar )
  4. Benutze dict und erstelle am Ende einen DataFrame ( ShikharDuas Antwort )

Ergebnisse (in Sekunden):

|------------|-------------|-------------|-------------|
|  Approach  |  1000 rows  |  5000 rows  | 10 000 rows |
|------------|-------------|-------------|-------------|
| .append    |    0.69     |    3.39     |    6.78     |
|------------|-------------|-------------|-------------|
| .loc w/o   |    0.74     |    3.90     |    8.35     |
| prealloc   |             |             |             |
|------------|-------------|-------------|-------------|
| .loc with  |    0.24     |    2.58     |    8.70     |
| prealloc   |             |             |             |
|------------|-------------|-------------|-------------|
|  dict      |    0.012    |   0.046     |   0.084     |
|------------|-------------|-------------|-------------|

Danke auch an @ krassowski für den nützlichen Kommentar - ich habe den Code aktualisiert.

Also benutze ich zusätzlich das Wörterbuch für mich.


Code:

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)

P.S. Ich glaube, meine Umsetzung ist nicht perfekt, und vielleicht gibt es Optimierungen.

85
Mikhail_Sam
mycolumns = ['A', 'B']
df = pd.DataFrame(columns=mycolumns)
rows = [[1,2],[3,4],[5,6]]
for row in rows:
    df.loc[len(df)] = row
65
Lydia

Informationen zum effizienten Anhängen finden Sie unter Hinzufügen einer zusätzlichen Zeile zu einem pandas -Datenrahmen und Einstellung mit Vergrößerung .

Fügen Sie Zeilen durch loc/ix für nicht vorhandene Schlüsselindexdaten hinzu. z.B. :

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

Oder:

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
65

Mit der Option ignore_index können Sie eine einzelne Zeile als Wörterbuch anhängen.

>>> 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
53
W.P. McNeill

Um der Pythonic willen, füge hier meine Antwort hinzu:

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
38
hkyi

Sie können auch eine Liste von Listen erstellen und in einen Datenrahmen konvertieren.

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)

geben

 i Doppelquadrat 
 0 0 0 0 
 1 1 2 1 
 2 2 4 4 
 3 3 6 9 
 4 4 8 16 
 5 5 10 25 
15
Brian Burns

Dies ist keine Antwort auf die OP-Frage, sondern ein Spielzeugbeispiel zur Veranschaulichung der Antwort von @ShikharDua, die ich oben als sehr nützlich empfunden habe.

Während dieses Fragment trivial ist, hatte ich in den tatsächlichen Daten 1000 Zeilen und viele Spalten und wollte in der Lage sein, nach verschiedenen Spalten zu gruppieren und dann die folgenden Statistiken für mehr als eine Taget-Spalte durchzuführen. Eine zuverlässige Methode zum Erstellen des Datenrahmens in einer Zeile zu einem Zeitpunkt zu haben, war daher eine große Bequemlichkeit. Vielen Dank @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

Einfach und nett herausgefunden:

>>> 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
10
Qinsi

Hier ist die Möglichkeit, eine Zeile in pandas DataFrame hinzuzufügen/anzuhängen

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

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

Es kann verwendet werden, um eine Zeile in einen leeren oder gefüllten pandas DataFrame einzufügen/anzufügen

6
Shivam Agrawal

Erstellen Sie ein neuer Datensatz (Datenrahmen) und fügen Sie alter_Datenrahmen hinzu.
Liste der Werte und der entsprechenden Spalte Namen übergeben, um einen neuen Datensatz (Datenrahmen) zu erstellen

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

Ein anderer Weg, es zu tun (wahrscheinlich nicht sehr performant):

# 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))

Sie können die DataFrame-Klasse auch folgendermaßen erweitern:

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

Mach es einfach. Indem Sie die Liste als Eingabe nehmen, die als Zeile im Datenrahmen angehängt wird:

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)
1
Vineet Jain
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

Wir sehen oft das Konstrukt df.loc[subscript] = …, das einer DataFrame-Zeile zugewiesen wird. Mikhail_Sam hat Benchmarks gepostet, der unter anderem dieses Konstrukt sowie die Methode enthält, die verwendet, und am Ende DataFrame diktiert und erstellt . Er fand, dass Letzteres bei weitem das schnellste war. Wenn wir jedoch den df3.loc[i] = … (mit dem vorab zugewiesenen DataFrame) in seinem Code durch df3.values[i] = … ersetzen, ändert sich das Ergebnis erheblich, da diese Methode ähnlich der mit dict abläuft. Deshalb sollten wir öfter die Verwendung von df.values[subscript] = … in Betracht ziehen. Beachten Sie jedoch, dass .values einen nullbasierten Index verwendet, der sich möglicherweise vom DataFrame.index unterscheidet.

0
Armali