Wenn Sie hierher gekommen sind und nach Informationen zu wie .__ gesucht haben. fügen Sie eine
DataFrame
undSeries
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
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.
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)
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.
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
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.