Spalte im Datenrahmen aus Liste hinzufügen

90

Ich habe einen Datenrahmen mit einigen Spalten wie dieser:

A   B   C  
0   
4
5
6
7
7
6
5

Der mögliche Wertebereich in A liegt nur zwischen 0 und 7 .

Außerdem habe ich eine Liste von 8 Elementen wie folgt:

List=[2,5,6,8,12,16,26,32]  //There are only 8 elements in this list

Wenn das Element in Spalte A n ist , muss ich das n- te Element aus der Liste in eine neue Spalte einfügen , z. B. 'D'.

Wie kann ich dies auf einmal tun, ohne den gesamten Datenrahmen zu durchlaufen?

Der resultierende Datenrahmen würde folgendermaßen aussehen:

A   B   C   D
0           2
4           12
5           16
6           26
7           32
7           32
6           26
5           16

Hinweis: Der Datenrahmen ist sehr groß und die Iteration ist die letzte Option. Ich kann die Elemente in 'List' aber auch in einer anderen Datenstruktur wie diktieren, falls erforderlich.

Mähne
quelle
1
Ich denke, Sie brauchen ein (kleineres) Spielzeugbeispiel mit dem gewünschten Ergebnis. Es klingt ein wenig vage atm.
Andy Hayden
10
Nennen Sie niemals eine Variable "Liste". In jeder Sprache.
lucid_dreamer

Antworten:

49

IIUC, wenn Sie Ihr (leider benanntes) Listzu einem machen ndarray, können Sie es einfach auf natürliche Weise indizieren.

>>> import numpy as np
>>> m = np.arange(16)*10
>>> m[df.A]
array([  0,  40,  50,  60, 150, 150, 140, 130])
>>> df["D"] = m[df.A]
>>> df
    A   B   C    D
0   0 NaN NaN    0
1   4 NaN NaN   40
2   5 NaN NaN   50
3   6 NaN NaN   60
4  15 NaN NaN  150
5  15 NaN NaN  150
6  14 NaN NaN  140
7  13 NaN NaN  130

Hier habe ich eine neue gebaut m, aber wenn Sie verwenden m = np.asarray(List), sollte das gleiche funktionieren: Die Werte in df.Awerden die entsprechenden Elemente von auswählen m.


Beachten Sie, dass Sie bei Verwendung einer alten Version von numpymöglicherweise m[df.A.values]stattdessen verwenden müssen - in der Vergangenheit numpyhaben Sie nicht gut mit anderen gespielt, und einige Umgestaltungen pandasverursachten Kopfschmerzen. Die Dinge haben sich jetzt verbessert.

DSM
quelle
Hallo @DSM. Ich verstehe, was Sie sagen, aber ich bekomme diesen Fehler: Traceback (most recent call last): File "./b.py", line 24, in <module> d["D"] = m[d.A] IndexError: unsupported iterator index
Mähne
1
@ Mane: Urf, das ist ein alter numpyFehler. Funktioniert d["D"] = m[d.A.values]für Sie?
DSM
270

Ordnen Sie die Liste einfach direkt zu:

df['new_col'] = mylist

Alternative
Konvertieren Sie die Liste in eine Reihe oder ein Array und weisen Sie dann zu:

se = pd.Series(mylist)
df['new_col'] = se.values

oder

df['new_col'] = np.array(mylist)
Spatz
quelle
3
pykernel_launcher.py:1: SettingWithCopyWarning: A value is trying to be set on a copy of a slice from a DataFrame. Try using .loc[row_indexer,col_indexer] = value instead See the caveats in the documentation: http://pandas.pydata.org/pandas-docs/stable/indexing.html#indexing-view-versus-copy """Entry point for launching an IPython kernel.
Ilya Rusin
@sparrow wird pd.Seriesden dtype verwenden? Ich meine, wird es Floats als Floats und Strings als Strings lassen? Oder werden die Elemente in der Liste standardmäßig Zeichenfolgen verwenden?
3kstc
2
@IlyaRusin, es ist ein falsches Positiv, das in diesem Fall ignoriert werden kann. Für weitere Informationen: stackoverflow.com/questions/20625582/…
Spatz
1
Dies kann vereinfacht werden zu: df ['new_col'] = pd.Series (mylist) .values
smartse
14

Eine Lösung, die die großartige von @sparrow verbessert.

Lassen Sie df Ihr Dataset sein und führen Sie die Liste mit den Werten auf, die Sie dem Datenrahmen hinzufügen möchten.

Angenommen, Sie möchten Ihre neue Spalte einfach new_column aufrufen

Machen Sie zuerst die Liste in eine Serie:

column_values = pd.Series(mylist)

Verwenden Sie dann die Einfügefunktion , um die Spalte hinzuzufügen. Mit dieser Funktion können Sie auswählen, an welcher Position Sie die Spalte platzieren möchten. Im folgenden Beispiel positionieren wir die neue Spalte an der ersten Position von links (durch Setzen von loc = 0).

df.insert(loc=0, column='new_column', value=column_values)
Salvatore Cosentino
quelle
Dies funktioniert nicht, wenn Sie Ihre Indizes von df in etwas anderes als 1,2,3 geändert haben. In diesem Fall müssen Sie zwischen den Zeilen Folgendes hinzufügen: column_values.index = df.index
Guy s
8

Lassen Sie uns zuerst den Datenrahmen erstellen, den Sie hatten. Ich werde die Spalten B und C ignorieren, da sie nicht relevant sind.

df = pd.DataFrame({'A': [0, 4, 5, 6, 7, 7, 6,5]})

Und das Mapping, das Sie wünschen:

mapping = dict(enumerate([2,5,6,8,12,16,26,32]))

df['D'] = df['A'].map(mapping)

Getan!

print df

Ausgabe:

   A   D
0  0   2
1  4  12
2  5  16
3  6  26
4  7  32
5  7  32
6  6  26
7  5  16
Phil Cooper
quelle
1
Ich denke, das OP weiß bereits, wie das geht. Beim Lesen wird das Problem Daus den Elementen von Aund List("Wenn das Element in Spalte A n ist, muss ich das n-te Element aus der Liste in eine neue Spalte einfügen, z. B. 'D'.")
DSM
SO hat sich in eine Art F (* & Nanny-Status verwandelt. Vielen Dank an @DSM für den Kommentar, aber ich konnte den Beitrag nicht korrigieren, bis er einer Peer-Review unterzogen wurde. Dann wurde er abgelehnt, weil er zu schnell war. Und dann war ich es In der Lage, meine eigene Bearbeitung zu überprüfen. Und dann ist es zu spät, weil eine schlechtere (IMHO) Antwort "akzeptiert" wurde. SO gibt es wirklich einige Meta-Nannys, die weniger als hilfreich sind !!!!
Phil Cooper
Nun, ich kann nicht für die Kindermädchen sprechen, aber Sie werden feststellen, dass Ihr Ansatz auf langen Arrays um eine Größenordnung langsamer ist. In anderer Hinsicht ist die Wahl zwischen np.array(List)[df.A]und df["A"].map(dict(enumerate(List)))meistens eine Frage der Präferenz.
DSM
Hallo Phil, ich habe nur Ihre Lösung und den Kommentar von DSM gesehen und bin dann nie darauf zurückgekommen, da die Lösung von DSM für mich gut funktioniert hat. Wenn Sie sich jetzt Ihre Lösung ansehen, funktioniert sie auch. Ich habe die DSM-Lösung für meinen Datensatz mit etwa 200.000 Einträgen ausgeführt und sie wird mit allen anderen Berechnungen, die ich habe, in wenigen Sekunden ausgeführt. Ich bin völlig neu in Python-Pandas und habe persönlich nichts Elegantes oder Großartiges gesucht. Was auch immer funktionierte, war in Ordnung. Aber ehrlich gesagt, danke für die Lösung.
Mähne
1

Alte Frage; aber ich versuche immer, den schnellsten Code zu verwenden!

Ich hatte eine riesige Liste mit 69 Millionen uint64. np.array () war für mich am schnellsten.

df['hashes'] = hashes
Time spent: 17.034842014312744

df['hashes'] = pd.Series(hashes).values
Time spent: 17.141014337539673

df['key'] = np.array(hashes)
Time spent: 10.724546194076538
Mehdi
quelle