Fügen Sie eine Zeile in den Pandas-Datenrahmen ein

111

Ich habe einen Datenrahmen:

s1 = pd.Series([5, 6, 7])
s2 = pd.Series([7, 8, 9])

df = pd.DataFrame([list(s1), list(s2)],  columns =  ["A", "B", "C"])

   A  B  C
0  5  6  7
1  7  8  9

[2 rows x 3 columns]

und ich muss eine erste Zeile [2, 3, 4] hinzufügen, um zu erhalten:

   A  B  C
0  2  3  4
1  5  6  7
2  7  8  9

Ich habe versucht append()und concat()funktioniert, kann aber nicht den richtigen Weg finden, wie das geht.

Wie füge ich Serien zum Datenrahmen hinzu / füge sie ein?

Meloun
quelle
6
Beachten Sie, dass es besser ist, s1.valuesals list(s1)eine völlig neue Liste mit zu erstellen list(s1).
Acushner
7
Ich verstehe nicht, warum jeder Pandas so sehr liebt, wenn etwas, das so einfach sein sollte, so schmerzhaft und so langsam ist.
MattCochrane

Antworten:

144

Weisen Sie einem bestimmten Index einfach eine Zeile zu loc:

 df.loc[-1] = [2, 3, 4]  # adding a row
 df.index = df.index + 1  # shifting index
 df = df.sort_index()  # sorting by index

Und Sie erhalten wie gewünscht:

    A  B  C
 0  2  3  4
 1  5  6  7
 2  7  8  9

Siehe in der Pandas-Dokumentation Indexierung: Einstellung mit Vergrößerung .

Piotr Migdal
quelle
2
Wenn Sie nicht mit Vergrößerung festlegen möchten, sondern in den Datenrahmen einfügen möchten, besuchen
Sie
6
Alternative zum Verschieben des Index: df.sort (). reset_index (drop = True)
Meloun
2
df.sort ist veraltet, verwenden Sie df.sort_index ()
GBGOLC
1
@Piotr - das funktioniert großartig, aber was passiert, wenn Sie eine Zeile aus Ihrem Datenrahmen duplizieren möchten, z. B. df.loc[-1] = df.iloc[[0]]und diese einfügen möchten ? Der Rahmen kommt mit einer hinzugefügten Indexspalte , die Fehler anzeigtValueError: cannot set a row with mismatched columns (siehe stackoverflow.com/questions/47340571/… )
Growler
5
Ich denke, es df.loc[-1] = [2, 3, 4] # adding a rowist ein bisschen irreführend, da -1es nicht die letzte Zeile / das letzte Element ist, wie es für Python-Arrays ist.
flow2k
26

Ich bin mir nicht sicher, wie Sie angerufen haben, concat()aber es sollte funktionieren, solange beide Objekte vom gleichen Typ sind. Vielleicht besteht das Problem darin, dass Sie Ihren zweiten Vektor in einen Datenrahmen umwandeln müssen? Die Verwendung des von Ihnen definierten df funktioniert für mich:

df2 = pd.DataFrame([[2,3,4]], columns=['A','B','C'])
pd.concat([df2, df])
mgilbert
quelle
Beste Antwort ^ :)
Cam.Davidson.Pilon
23

Ein Weg, dies zu erreichen, ist

>>> pd.DataFrame(np.array([[2, 3, 4]]), columns=['A', 'B', 'C']).append(df, ignore_index=True)
Out[330]: 
   A  B  C
0  2  3  4
1  5  6  7
2  7  8  9

Im Allgemeinen ist es am einfachsten, Datenrahmen und keine Serien anzuhängen. In Ihrem Fall pd.prepend()erstelle ich zuerst den neuen Datenrahmen und hänge dann Ihren alten an , da die neue Zeile "oben" (mit Start-ID) sein soll und keine Funktion vorhanden ist .

ignore_indexignoriert den alten laufenden Index in Ihrem Datenrahmen und stellt sicher, dass die erste Zeile tatsächlich mit dem Index beginnt, 1anstatt mit dem Index neu zu starten 0.

Typischer Haftungsausschluss: Cetero censeo ... das Anhängen von Zeilen ist eine recht ineffiziente Operation. Wenn Sie über die Leistung kümmern und können irgendwie gewährleisten, zunächst einen Datenrahmen mit dem richtigen (mehr) Index erstellen und dann nur das Einfügen der zusätzliche Zeile in den Datenrahmen, sollten Sie auf jeden Fall tun. Sehen:

>>> index = np.array([0, 1, 2])
>>> df2 = pd.DataFrame(columns=['A', 'B', 'C'], index=index)
>>> df2.loc[0:1] = [list(s1), list(s2)]
>>> df2
Out[336]: 
     A    B    C
0    5    6    7
1    7    8    9
2  NaN  NaN  NaN
>>> df2 = pd.DataFrame(columns=['A', 'B', 'C'], index=index)
>>> df2.loc[1:] = [list(s1), list(s2)]

Bisher haben wir das, was Sie hatten als df:

>>> df2
Out[339]: 
     A    B    C
0  NaN  NaN  NaN
1    5    6    7
2    7    8    9

Jetzt können Sie die Zeile einfach wie folgt einfügen. Da der Raum vorbelegt wurde, ist dies effizienter.

>>> df2.loc[0] = np.array([2, 3, 4])
>>> df2
Out[341]: 
   A  B  C
0  2  3  4
1  5  6  7
2  7  8  9
FooBar
quelle
Das ist eine nette Workarround-Lösung. Ich habe versucht, Serien in den Datenrahmen einzufügen. Es ist im Moment gut genug für mich.
Meloun
Mir gefällt am meisten die letzte Option. Das passt wirklich zu dem, was ich wirklich tun möchte. Vielen Dank, dass Sie @FooBar!
Jade Cacho
13

Ich habe eine kurze Funktion zusammengestellt, die etwas mehr Flexibilität beim Einfügen einer Zeile ermöglicht:

def insert_row(idx, df, df_insert):
    dfA = df.iloc[:idx, ]
    dfB = df.iloc[idx:, ]

    df = dfA.append(df_insert).append(dfB).reset_index(drop = True)

    return df

was weiter verkürzt werden könnte zu:

def insert_row(idx, df, df_insert):
    return df.iloc[:idx, ].append(df_insert).append(df.iloc[idx:, ]).reset_index(drop = True)

Dann könnten Sie etwas verwenden wie:

df = insert_row(2, df, df_new)

wo 2ist die Indexposition in dfdem Sie einfügen möchten df_new.

elPastor
quelle
7

Wir können verwenden numpy.insert. Dies hat den Vorteil der Flexibilität. Sie müssen nur den Index angeben, in den Sie einfügen möchten.

s1 = pd.Series([5, 6, 7])
s2 = pd.Series([7, 8, 9])

df = pd.DataFrame([list(s1), list(s2)],  columns =  ["A", "B", "C"])

pd.DataFrame(np.insert(df.values, 0, values=[2, 3, 4], axis=0))

    0   1   2
0   2   3   4
1   5   6   7
2   7   8   9

Denn np.insert(df.values, 0, values=[2, 3, 4], axis=0)0 teilt der Funktion den Ort / Index mit, an dem Sie die neuen Werte platzieren möchten.

Tai
quelle
6

Das mag zu einfach erscheinen, aber es ist unglaublich, dass eine einfache Funktion zum Einfügen neuer Zeilen nicht integriert ist. Ich habe viel darüber gelesen, wie man eine neue df an das Original anfügt, aber ich frage mich, ob dies schneller wäre.

df.loc[0] = [row1data, blah...]
i = len(df) + 1
df.loc[i] = [row2data, blah...]
Aaron Melgar
quelle
Meinten Sie "eine neue df anhängen" oder nur "eine neue Zeile anhängen", wie Ihr Code zeigt?
smci
Entschuldigung, mein Satz war nicht klar. Ich habe andere Leute Lösungen gelesen, die einen ganz neuen Datenrahmen mit nur einer einzigen Zeile zusammenfassen / anhängen. In meiner Lösung ist es jedoch nur eine einzelne Zeile im vorhandenen Datenrahmen, ohne dass ein zusätzlicher Datenrahmen erstellt werden muss
Aaron Melgar,
5

Im Folgenden finden Sie die beste Möglichkeit, eine Zeile in den Pandas-Datenrahmen einzufügen, ohne einen Index zu sortieren und zurückzusetzen:

import pandas as pd

df = pd.DataFrame(columns=['a','b','c'])

def insert(df, row):
    insert_loc = df.index.max()

    if pd.isna(insert_loc):
        df.loc[0] = row
    else:
        df.loc[insert_loc + 1] = row

insert(df,[2,3,4])
insert(df,[8,9,0])
print(df)
Sagar Rathod
quelle
Warum würdest du sagen, dass dies der beste Weg ist?
Yuca
dann wäre es schön, Beweise für diese Behauptung vorzulegen, haben Sie es zeitlich festgelegt?
Yuca
1
Sie können pd.isna verwenden, um den Import von numpy zu vermeiden
kato2
1

concat()scheint etwas schneller zu sein als das Einfügen und Neuindizieren der letzten Zeile. Für den Fall, dass sich jemand über die Geschwindigkeit zweier Top-Ansätze wundern würde:

In [x]: %%timeit
     ...: df = pd.DataFrame(columns=['a','b'])
     ...: for i in range(10000):
     ...:     df.loc[-1] = [1,2]
     ...:     df.index = df.index + 1
     ...:     df = df.sort_index()

17,1 s ± 705 ms pro Schleife (Mittelwert ± Standardabweichung von 7 Läufen, jeweils 1 Schleife)

In [y]: %%timeit
     ...: df = pd.DataFrame(columns=['a', 'b'])
     ...: for i in range(10000):
     ...:     df = pd.concat([pd.DataFrame([[1,2]], columns=df.columns), df])

6,53 s ± 127 ms pro Schleife (Mittelwert ± Standardabweichung von 7 Läufen, jeweils 1 Schleife)

M. Viaz
quelle
1

Es ist ziemlich einfach, einer Pandas eine Zeile hinzuzufügen DataFrame:

  1. Erstellen Sie ein reguläres Python-Wörterbuch mit denselben Spaltennamen wie Ihr Dataframe;

  2. Verwenden Sie die pandas.append()Methode und übergeben Sie den Namen Ihres Wörterbuchs. Dabei .append()handelt es sich um eine Methode für DataFrame-Instanzen.

  3. Fügen Sie ignore_index=Truedirekt nach Ihrem Wörterbuchnamen hinzu.

Pepe
quelle
Dies ist wahrscheinlich die am meisten bevorzugte Option (ca. 2020).
David Golembiowski
0

Sie können die Zeile einfach an das Ende des DataFrame anhängen und dann den Index anpassen.

Zum Beispiel:

df = df.append(pd.DataFrame([[2,3,4]],columns=df.columns),ignore_index=True)
df.index = (df.index + 1) % len(df)
df = df.sort_index()

Oder verwenden concatals:

df = pd.concat([pd.DataFrame([[1,2,3,4,5,6]],columns=df.columns),df],ignore_index=True)
Xinyi Li
quelle
-1

Der einfachste Weg, eine Zeile in einen Pandas-Datenrahmen einzufügen, ist:

DataFrame.loc[ location of insertion ]= list( )

Beispiel:

DF.loc[ 9 ] = [ ´Pepe , 33, ´Japan ]

NB: Die Länge Ihrer Liste sollte mit der des Datenrahmens übereinstimmen.

Pepe
quelle
hat den Trick für mich gemacht!
Sam Shaw