Erstellen neuer Spalten durch Iterieren über Zeilen im Pandas-Datenrahmen

10

Ich habe einen Pandas-Datenrahmen (X11) wie folgt: Tatsächlich habe ich 99 Spalten bis zu dx99

    dx1      dx2    dx3    dx4
0   25041   40391   5856    0
1   25041   40391   25081   5856
2   25041   40391   42822   0
3   25061   40391   0       0
4   25041   40391   0       5856
5   40391   25002   5856    3569

Ich möchte zusätzliche Spalten für Zellenwerte wie 25041,40391,5856 usw. erstellen. Es wird also eine Spalte 25041 mit dem Wert 1 oder 0 geben, wenn 25041 in dieser bestimmten Zeile in einer beliebigen dxs-Spalte vorkommt. Ich verwende diesen Code und er funktioniert, wenn die Anzahl der Zeilen geringer ist.

mat = X11.as_matrix(columns=None)
values, counts = np.unique(mat.astype(str), return_counts=True)

for x in values:
    X11[x] = X11.isin([x]).any(1).astype(int)

Ich bekomme folgendes Ergebnis:

dx1     dx2     dx3    dx4  0   25002   25041   25061   25081   3569    40391   42822   5856
25041   40391   5856    0   0   0       1       0       0       0          1        0       1
25041   40391   25081  5856 0   0       1       0       1       0            1      0       1
25041   40391   42822   0   0   0       1       0       0       0           1       1       0
25061   40391   0       0   0   0       0       1       0       0          1        0       0
25041   40391   0    5856   0   0       1       0       0       0          1        0       1
40391   25002 5856   3569   0   1       0       0       0       1          1        0       1

Wenn die Anzahl der Zeilen viele Tausend oder in Millionen beträgt, hängt es und dauert ewig, und ich erhalte kein Ergebnis. Bitte beachten Sie, dass die Zellenwerte nicht nur für Spalten gelten, sondern sich in mehreren Spalten wiederholen. Zum Beispiel kommt 40391 sowohl in dx1 als auch in dx2 usw. für 0 und 5856 usw. vor. Haben Sie eine Idee, wie Sie die oben erwähnte Logik verbessern können?

Sanoj
quelle
Irgendeine Idee, wie man das löst? Ich warte immer noch darauf, dass dies behoben wird, da meine Daten immer größer werden und die vorhandene Lösung für immer benötigt wird, um Dummy-Spalten zu generieren.
Sanoj

Antworten:

6

Es gibt eine viel pythonischere Lösung in Pandas ...

Bei 10 Millionen Zeilen auf meinem Laptop dauert dies weniger als eine Sekunde:

for x in X11.E.unique():
    X11[x]=(X11.E==x).astype(int)
X11

Hier sind die Details aufgeführt:

Einfacher kleiner Datenrahmen -

import numpy as np
import pandas as pd

X11 = pd.DataFrame(np.random.randn(6,4), columns=list('ABCD'))
X11['E'] = [25223, 112233,25223,14333,14333,112233]
X11

einfacher kleiner Datenrahmen

Binarisierungsmethode -

for x in X11.E.unique():
    X11[x]=(X11.E==x).astype(int)
X11

Geben Sie hier die Bildbeschreibung ein

Datenrahmen mit 10 Millionen Zeilen -

pd.set_option("display.max_rows",20)
X12 = pd.DataFrame(np.random.randn(10000000,4), columns=list('ABCD'))
foo = [25223, 112233,25223,14333,14333,112233]
bar=[]
import random
for x in range(10000000):
    bar.append(random.choice(foo))
X12['E'] = bar
X12

Geben Sie hier die Bildbeschreibung ein

Zeitgesteuerte Binärisierung (auch bekannt als One-Hot-Codierung) für 10 Millionen Zeilendatenrahmen -

import time
start = time.clock()

for x in X12.E.unique():
    X12[x]=(X12.E==x).astype(int)
elapsed = (time.clock() - start)

print "This is the time that this took in seconds: ",elapsed

X12

Geben Sie hier die Bildbeschreibung ein

Hoffe das hilft!

AN6U5
quelle
Dies sagt nicht aus, wie Sie dynamisch Dummy-Werte (25041) und Spaltennamen (dh dx1) in der for-Schleife erhalten. Ich kann immer nur einen bekommen.
Sanoj
Schauen Sie jetzt. Ich habe alle Details hinzugefügt.
AN6U5
Ihre Lösung sieht gut aus, wenn ich Dummy-Werte nur in einer Spalte erstellen muss, wie Sie es von "E" aus getan haben. Aber wenn ich es aus mehreren Spalten erstellen muss und diese Zellenwerte nicht für eine bestimmte Spalte eindeutig sind, muss ich dann Ihren Code für alle diese Spalten erneut schleifen? Wenn dies der Fall ist, wie wird dann für die Wiederholung von Werten gesorgt? Andernfalls wird die vorherige Dummy-Spalte, die mit demselben Namen erstellt wurde, überschrieben. Ich habe mein fragliches Ergebnis oben hinzugefügt, um zu verdeutlichen, ob es Verwirrung gab. Trotzdem danke, dass du dich damit befasst hast.
Sanoj
4

Es sieht so aus, als ob Sie eine Dummy-Variable aus einer Pandas-Datenrahmenspalte erstellen möchten. Glücklicherweise hat Pandas eine spezielle Methode dafür : get_dummies(). Hier ist ein Code-Snippet, das Sie an Ihre Bedürfnisse anpassen können:

import pandas as pd
data = pd.read_clipboard(sep=',')

#get the names of the first 3 columns
colN = data.columns.values[:3]

#make a copy of the dataframe
data_transformed = data

#the get_dummies method is doing the job for you
for column_name in colN:
    dummies = pd.get_dummies(data_transformed[column_name], prefix='value', prefix_sep='_')
    col_names_dummies = dummies.columns.values

    #then you can append new columns to the dataframe
    for i,value in enumerate(col_names_dummies):
        data_transformed[value] = dummies.iloc[:,i]

Hier ist die Ausgabe von data_transformed:

         dx1    dx2    dx3   dx4    dx5    dx6    dx7  value_25041  value_25061  0  25041  40391   5856     0  V4511  V5867  30000            1            0   
    1  25041  40391  25081  5856   5363   3572      0            1            0   
    2  25041  40391  42822     0   5856      0      0            1            0   
    3  25061  40391      0     0      0      0      0            0            1   
    4  25041  40391      0  5856  25081  V4511  25051            1            0   

      value_40391  value_0  value_5856  value_25081  value_42822  
    0            1        0           1            0            0  
    1            1        0           0            1            0  
    2            1        0           0            0            1  
    3            1        1           0            0            0  
    4            1        1           0            0            0  
Michaelg
quelle
Es sieht in Ordnung aus, aber wenn Sie es genau sehen, werden Sie feststellen, dass es für value_0 nicht in allen Zeilen 1 gibt. Da in allen Zeilen 0 vorhanden ist, sollte value_0 in allen Zeilen 1 haben. Gleiches gilt für value_5856, Value_25081 usw. Es scheint, dass diese Logik Werte aus einer Spalte auswählt und dann nicht zurückgeht, sondern vorwärts geht.
Sanoj
Hallo Sanoj. Es ist nicht wirklich fair, meine Lösung zu verwenden und mich abzustimmen. Das Mindeste, was Sie tun können, ist, Ihre Frage mit den neuen Fortschritten zu aktualisieren, anstatt eine neue Frage zu öffnen. Wenn Sie möchten, dass Ihnen Menschen helfen, sollten Sie nett mit ihnen spielen.
Michaelg
Hallo michaeld: Ich hatte nicht die Absicht dich abzustimmen. Ich habe gerade das Klickzeichen entfernt, da diese Lösung meine Anforderungen nicht erfüllt hat. Anfangs dachte ich OK, aber später, als ich nachforschte, fand ich die Diskrepanzen, wie in der obigen Antwort erwähnt. Ich habe keine Antwort darauf erhalten, daher habe ich eine neue Frage erstellt, in der ich meine ursprüngliche Antwort erwähnt und Ihre Antwort mit der erforderlichen Korrektur aufgenommen habe. Entschuldigung, ich habe Ihren Namen dort nicht erwähnt. Ich werde das aktualisieren.
Sanoj