it-swarm.com.de

Wie füge ich Zeilen in einem pandas dataframe in einer for-Schleife an?

Ich habe folgende for-Schleife:

for i in links:
     data = urllib2.urlopen(str(i)).read()
     data = json.loads(data)
     data = pd.DataFrame(data.items())
     data = data.transpose()
     data.columns = data.iloc[0]
     data = data.drop(data.index[[0]])

Jeder so erstellte Datenrahmen hat die meisten Spalten gemeinsam, jedoch nicht alle. Außerdem haben sie alle nur eine Reihe. Was ich tun muss, ist, dem Datenrahmen alle unterschiedlichen Spalten und jede Zeile von jedem Datenrahmen hinzuzufügen, der von der for-Schleife erzeugt wird

Ich habe versucht, pandas verketten oder ähnliches, aber nichts schien zu funktionieren. Irgendeine Idee? Danke.

48
Blue Moon

Angenommen, Ihre Daten sehen folgendermaßen aus:

import pandas as pd
import numpy as np

np.random.seed(2015)
df = pd.DataFrame([])
for i in range(5):
    data = dict(Zip(np.random.choice(10, replace=False, size=5),
                    np.random.randint(10, size=5)))
    data = pd.DataFrame(data.items())
    data = data.transpose()
    data.columns = data.iloc[0]
    data = data.drop(data.index[[0]])
    df = df.append(data)
print('{}\n'.format(df))
# 0   0   1   2   3   4   5   6   7   8   9
# 1   6 NaN NaN   8   5 NaN NaN   7   0 NaN
# 1 NaN   9   6 NaN   2 NaN   1 NaN NaN   2
# 1 NaN   2   2   1   2 NaN   1 NaN NaN NaN
# 1   6 NaN   6 NaN   4   4   0 NaN NaN NaN
# 1 NaN   9 NaN   9 NaN   7   1   9 NaN NaN

Dann könnte es mit ersetzt werden

np.random.seed(2015)
data = []
for i in range(5):
    data.append(dict(Zip(np.random.choice(10, replace=False, size=5),
                         np.random.randint(10, size=5))))
df = pd.DataFrame(data)
print(df)

Bilden Sie also nicht für jede Zeile einen neuen DataFrame. Sammeln Sie stattdessen alle Daten in einer Liste von Dikten und rufen Sie am Ende einmal außerhalb der Schleife df = pd.DataFrame(data) auf.

Jeder Aufruf von df.append Erfordert die Zuweisung von Speicherplatz für einen neuen DataFrame mit einer zusätzlichen Zeile, das Kopieren aller Daten vom ursprünglichen DataFrame in den neuen DataFrame und das anschließende Kopieren der Daten in die neue Zeile. All diese Zuweisung und das Kopieren machen das Aufrufen von df.append In einer Schleife sehr ineffizient. Der Zeitaufwand für das Kopieren wächst quadratisch mit der Anzahl der Zeilen. Der Call-DataFrame-Once-Code ist nicht nur einfacher zu schreiben, sondern auch leistungsfähiger - die Zeitkosten für das Kopieren steigen linear mit der Anzahl der Zeilen.

52
unutbu

Es gibt zwei Gründe, warum Sie Zeilen in einer Schleife anfügen können: 1. Zu einem vorhandenen df hinzufügen und 2. Einen neuen df erstellen.

um einen neuen df zu erstellen, ist es meiner Meinung nach gut dokumentiert, dass Sie entweder Ihre Daten als Liste erstellen und dann den Datenrahmen erstellen sollten:

cols = ['c1', 'c2', 'c3']
lst = []
for a in range(2):
    lst.append([1, 2, 3])
df1 = pd.DataFrame(lst, columns=cols)
df1
Out[3]: 
   c1  c2  c3
0   1   2   3
1   1   2   3

ODER Erstellen Sie den Datenrahmen mit einem Index und fügen Sie ihn hinzu

cols = ['c1', 'c2', 'c3']
df2 = pd.DataFrame(columns=cols, index=range(2))
for a in range(2):
    df2.loc[a].c1 = 4
    df2.loc[a].c2 = 5
    df2.loc[a].c3 = 6
df2
Out[4]: 
  c1 c2 c3
0  4  5  6
1  4  5  6

Wenn Sie zu einem vorhandenen Datenrahmen hinzufügen möchten, können Sie eine der beiden oben genannten Methoden verwenden und dann die df zusammenfügen (mit oder ohne Index):

df3 = df2.append(df1, ignore_index=True)
df3
Out[6]: 
  c1 c2 c3
0  4  5  6
1  4  5  6
2  1  2  3
3  1  2  3

Sie können auch eine Liste mit Wörterbucheinträgen erstellen und diese wie in der obigen Antwort anhängen.

lst_dict = []
for a in range(2):
    lst_dict.append({'c1':2, 'c2':2, 'c3': 3})
df4 = df1.append(lst_dict)
df4
Out[7]: 
   c1  c2  c3
0   1   2   3
1   1   2   3
0   2   2   3
1   2   2   3

Verwenden des Diktats (Zip (cols, vals))

lst_dict = []
for a in range(2):
    vals = [7, 8, 9]
    lst_dict.append(dict(Zip(cols, vals)))
df5 = df1.append(lst_dict)
49
kztd

Ich habe mit Hilfe eines temporären leeren Datenrahmens einen Datenrahmen in einer for-Schleife erstellt. Denn bei jeder Iteration der for-Schleife wird ein neuer Datenrahmen erstellt, wodurch der Inhalt der vorherigen Iteration überschrieben wird.

Daher muss ich den Inhalt des Datenrahmens in den leeren Datenrahmen verschieben, der bereits erstellt wurde. So einfach ist das. Wir müssen nur die .append-Funktion verwenden, wie unten gezeigt:

temp_df = pd.DataFrame() #Temporary empty dataframe
for sent in Sentences:
    New_df = pd.DataFrame({'words': sent.words}) #Creates a new dataframe and contains tokenized words of input sentences
    temp_df = temp_df.append(New_df, ignore_index=True) #Moving the contents of newly created dataframe to the temporary dataframe

Außerhalb der for-Schleife können Sie den Inhalt des temporären Datenrahmens in den Master-Datenrahmen kopieren und dann den temporären Datenrahmen löschen, wenn Sie ihn nicht benötigen

4
JKC

Ein kompakterer und effizienterer Weg wäre vielleicht:

cols = ['frame', 'count']
N = 4
dat = pd.DataFrame(columns = cols)
for i in range(N):

    dat = dat.append({'frame': str(i), 'count':i},ignore_index=True)

ausgabe wäre:

>>> dat
   frame count
0     0     0
1     1     1
2     2     2
3     3     3
1
Ayanava Sarkar