web-dev-qa-db-de.com

So fügen Sie eine Serie und einen DataFrame zusammen

Wenn Sie hierher gekommen sind und nach Informationen zu wie .__ gesucht haben. fügen Sie eine DataFrame und Series auf den Index ein, sehen Sie sich bitte this .__ an. Antworten .

Die ursprüngliche Absicht des OP bestand darin, zu fragen, wie man Serienelemente als Spalten zu einem anderen DataFrame. Wenn Sie daran interessiert sind, die Antworten Sie auf diese, schauen Sie sich die akzeptierte Antwort von EdChum an.


Am besten kann ich mir einfallen lassen

df = pd.DataFrame({'a':[1, 2], 'b':[3, 4]})  # see EDIT below
s = pd.Series({'s1':5, 's2':6})

for name in s.index:
    df[name] = s[name]

   a  b  s1  s2
0  1  3   5   6
1  2  4   5   6

Kann jemand eine bessere Syntax/schnellere Methode vorschlagen? 

Meine Versuche:

df.merge(s)
AttributeError: 'Series' object has no attribute 'columns'

und

df.join(s)
ValueError: Other Series must have a name

EDIT In den ersten beiden Antworten wurde ein Problem mit meiner Frage hervorgehoben. Verwenden Sie daher Folgendes, um df zu erstellen:

df = pd.DataFrame({'a':[np.nan, 2, 3], 'b':[4, 5, 6]}, index=[3, 5, 6])

mit dem Endergebnis

    a  b  s1  s2
3 NaN  4   5   6
5   2  5   5   6
6   3  6   5   6
41
Nathan Lloyd

Sie können einen Datenrahmen aus der Serie erstellen und dann mit dem Datenrahmen zusammenführen ..__ Sie geben also die Daten als Werte an, multiplizieren sie jedoch mit der Länge, setzen die Spalten auf den Index und setzen die Parameter für left_index und right_index auf True:

In [27]:

df.merge(pd.DataFrame(data = [s.values] * len(s), columns = s.index), left_index=True, right_index=True)
Out[27]:
   a  b  s1  s2
0  1  3   5   6
1  2  4   5   6

EDITFür die Situation, in der der Index des erstellten Df aus der Serie den Index des Df verwenden soll, können Sie Folgendes tun:

df.merge(pd.DataFrame(data = [s.values] * len(df), columns = s.index, index=df.index), left_index=True, right_index=True)

Dies setzt voraus, dass die Indizes der Länge entsprechen.

15
EdChum

Update
Ab v0.24.0 können Sie auf DataFrame und Series zusammenführen, solange die Series benannt ist. 

df.merge(s.rename('new'), left_index=True, right_index=True)
# If series is already named,
# df.merge(s, left_index=True, right_index=True)

Heutzutage können Sie die Serie einfach mit to_frame () in einen DataFrame konvertieren. Also (wenn Sie auf Index gehen):

df.merge(s.to_frame(), left_index=True, right_index=True)
106
Nicholas Morley

Hier ist ein Weg:

df.join(pd.DataFrame(s).T).fillna(method='ffill')

Zusammenbrechen, was hier passiert ...

pd.DataFrame(s).T erstellt einen einreihigen DataFrame aus s, der folgendermaßen aussieht:

   s1  s2
0   5   6

Als Nächstes verkettet join diesen neuen Frame mit df:

   a  b  s1  s2
0  1  3   5   6
1  2  4 NaN NaN

Zuletzt werden die NaN-Werte am Index 1 mit den vorherigen Werten in der Spalte gefüllt, wobei fillna mit dem Forward-fill-Argument (ffill) verwendet wird:

   a  b  s1  s2
0  1  3   5   6
1  2  4   5   6

Um fillna zu vermeiden, können Sie mit pd.concat die Zeilen des aus s erstellten Datenrahmens wiederholen. In diesem Fall lautet die allgemeine Lösung:

df.join(pd.concat([pd.DataFrame(s).T] * len(df), ignore_index=True))

Hier ist eine weitere Lösung zur Bewältigung der in der bearbeiteten Frage gestellten Indizierungsherausforderung:

df.join(pd.DataFrame(s.repeat(len(df)).values.reshape((len(df), -1), order='F'), 
        columns=s.index, 
        index=df.index))

s wird in einen DataFrame umgewandelt, indem die Werte wiederholt und umgeformt werden (unter Angabe der 'Fortran'-Reihenfolge). Außerdem werden die entsprechenden Spaltennamen und der entsprechende Index übergeben. Dieser neue DataFrame wird dann mit df verbunden.

3
Alex Riley

Wenn ich vorschlagen könnte, Ihre Datenframes so einzurichten (Auto-Indizierung):

df = pd.DataFrame({'a':[np.nan, 1, 2], 'b':[4, 5, 6]})

dann können Sie Ihre s1- und s2-Werte so einrichten (verwenden Sie shape (), um die Anzahl der Zeilen von df zurückzugeben):

s = pd.DataFrame({'s1':[5]*df.shape[0], 's2':[6]*df.shape[0]})

dann ist das gewünschte Ergebnis einfach:

display (df.merge(s, left_index=True, right_index=True))

Alternativ können Sie einfach die neuen Werte zu Ihrem Datenrahmen hinzufügen. Df: 

df = pd.DataFrame({'a':[nan, 1, 2], 'b':[4, 5, 6]})
df['s1']=5
df['s2']=6
display(df)

Beide kehren zurück:

     a  b  s1  s2
0  NaN  4   5   6
1  1.0  5   5   6
2  2.0  6   5   6

Wenn Sie eine andere Liste von Daten haben (anstatt nur einen einzigen anzuwendenden Wert), und Sie wissen, dass sie in derselben Reihenfolge wie df sind, z.

s1=['a','b','c']

dann können Sie dies auf dieselbe Weise anhängen:

df['s1']=s1

kehrt zurück:

     a  b s1
0  NaN  4  a
1  1.0  5  b
2  2.0  6  c
0
James

Sie können eine Pandas.DataFrame-Spalte problemlos auf eine Konstante setzen. Diese Konstante kann ein Int sein wie in Ihrem Beispiel. Wenn sich die von Ihnen angegebene Spalte nicht im Verzeichnis df befindet, erstellen Pandas eine neue Spalte mit dem von Ihnen angegebenen Namen. Nachdem Ihr Datenrahmen erstellt wurde (aus Ihrer Frage):

df = pd.DataFrame({'a':[np.nan, 2, 3], 'b':[4, 5, 6]}, index=[3, 5, 6])

Du kannst einfach laufen:

df['s1'], df['s2'] = 5, 6

Sie können eine Schleife oder ein Verständnis schreiben, um dies für alle Elemente in einer Liste von Tupeln oder für Schlüssel und Werte in einem Wörterbuch auszuführen, je nachdem, wie Sie Ihre echten Daten gespeichert haben.

0
Alex