Seite 1 von 1

hinzufügen von Spalten an ein array

Verfasst: Sonntag 24. April 2022, 01:40
von nichtSoGuter
Hallo,

ich habe einen Funktion geschrieben der 3 DataFrames übergeben werden. Ein Dataframe mit features X. Ein DataFrame mit Labels y. Und ein Dataframe (nenne ich im folgenden Z DataFrame) dessen Spalten dem Feature DataFrame X hinzugefügt werden sollen, wenn die die Spalten des Z Dataframes mit der Spalte des y Dataframes korrelieren.

kurz: wenn die Spalten des Z Dataframes mit dem y Dataframe korrelieren, dann werden die spalten des Z Dataframes dem X dataframe hinzugefügt

außerdem sollen die Namen der hinzugefügten spalten von Z in ein Array gespeichert werden. Das array soll ein attribut der klasse sein.

Ich habe probleme mit dem anhängen den Spalten vom Z DataFrame an das bestehende X DataFrame
- wenn ich np.hstack und bei np.append werden alle Spalten untereinander angefügt (wieso auch immer??)
- bei np.concatenate erscheint die Fehlermeldung: ValueError: all the input arrays must have same number of dimensions, but the array at index 0 has 2 dimension(s) and the array at index 1 has 1 dimension(s)

Die shape von den DataFrames sind
- von X Dataframe: (20640, 9) --> zu dem sollen die Spalten hinzugefügt werden
- von Z Dataframe: (20640, 2) --> die Spalten werden iteriert also ist der shape bei der zeile mit np.conatenate wahrscheinlich (20640, 1)

Ich sitze schon ziemlich lange dran und wäre endlos dankbar wenn mir jemand helfen könnte.
ich weiß nicht wie ich die Spalten sonst an das X Dataframe anhängen könnte


Mein Code

Code: Alles auswählen

# neue Spalte nur hinzfügen, wenn die Korrelation zwischen "median_house_value" (y Dataframe --> Label) und dem Attribut des Z Dataframes größer als 0.25 ist
from scipy import stats
class spaltenHinzufüger(BaseEstimator, TransformerMixin):
    # leere liste angelegt. Der liste werden die Spaltennamen der hinzugefügten Spalten hinzugefügt
    name_der_hinzugefügten_Spalten=[]
    def __init__(self):
        pass
    
    def fit(self,X,y=None):
        pass
    
    def transform(self, X, y, dataframe_mit_neuen_attributen):
        rückgabe = np.array(X)
        for spalten in dataframe_mit_neuen_attributen:
        # "spalten" ist der name einer Spalten. Spalte wird mit "dataframe_mit_neuen_attributen[spalten]" angesprochen
        
        # korrelationen werden berechnet
            spaer_korrelation = stats.spearmanr(dataframe_mit_neuen_attributen[spalten] ,y)
            pear_korrelation = stats.pearsonr(dataframe_mit_neuen_attributen[spalten] ,y)
            
          # abhängig von dem Wert der Korrelation werden die Spalten hinzugefügt oder nicht (wenn eines der Korrelation über 0.25 ist dann wird die spalte hinzugefügt)
            if(spaer_korrelation.correlation > 0.25 or pear_korrelation[0] > 0.25):
            
            	#name der hinzuzufügenden Spalte wird in liste (=attribut der klasse) gespeichert
                self.name_der_hinzugefügten_Spalten.append(spalten)
                
                # rückgabe varibale wird spalte hinzugefügt
                rückgabe= np.concatenate((rückgabe,dataframe_mit_neuen_attributen[spalten]),axis=1)
        return rückgabe   

Re: hinzufügen von Spalten an ein array

Verfasst: Sonntag 24. April 2022, 08:09
von __deets__
Nach der Beschreibung gehend klingt das unsinnig. Ein dataframe ist notwendigerweise immer rechteckig. Was du beschreibst klingt aber nach dem Versuch, eine Art “flattersatz” zu mache. Also den Frame nur ein einigen Zeilen zu verbreitern. Das kann der nicht.

Eine Lösung kann darin bestehen, Z so aufzubauen, dass leere oder ähnliche Zeilen da eingefügt werden, wo keine Korrelation herrscht. Damit dann Z in der vertikalen Dimension gleich X ist.

Re: hinzufügen von Spalten an ein array

Verfasst: Sonntag 24. April 2022, 08:39
von Sirius3
Kommentare werden immer so weit engerückt, wie der umgebende Block.
Klassennamen werden mit großm Anfangsbuchstaben geschrieben. Variablennamen schreibt man dagegen komplett klein.
Man benutzt keine globalen Klassenvariablen, Attribute werden in __init__ angelegt.
concatenate ist eine teure Operation, weil alle Daten kopiert werden müssen. Deshalb ruft man die nur einmal am Schluß auf.

Code: Alles auswählen

class SpaltenHinzufüger(BaseEstimator, TransformerMixin):
    def __init__(self):
        self.benutzte_spalten = []
    
    def fit(self,X,y=None):
        pass
    
    def transform(self, X, y, dataframe_mit_neuen_attributen):
        rückgabe = [X]
        for name, data in dataframe_mit_neuen_attributen.iteritems():
            # korrelationen werden berechnet
            spaer_korrelation = stats.spearmanr(data, y)
            pear_korrelation = stats.pearsonr(data, y)
            
            # abhängig von dem Wert der Korrelation werden die Spalten hinzugefügt oder nicht (wenn eines der Korrelation über 0.25 ist dann wird die spalte hinzugefügt)
            if spaer_korrelation.correlation > 0.25 or pear_korrelation[0] > 0.25:
                self.benutzte_spalten.append(name)
                # rückgabe varibale wird spalte hinzugefügt
                rückgabe.append(data.value.reshape(-1, 1))
        return np.concatenate(rückgabe, axis=1)
`TransformerMixin` erwartet eine transform-Methode mit nur einem X-Argument. Die Methode wird also so nicht funktionieren. Wie soll denn die Klasse benutzt werden?

Re: hinzufügen von Spalten an ein array

Verfasst: Sonntag 24. April 2022, 14:25
von nichtSoGuter
@ __deets__

ich habe das glaube ich bisschen missverständlich ausgedrückt sry. Es sollen keine Zeilen sondern Spalten hinzugefügt werden. Beide dataframes (X und Z) haben beide die selbe anzahl an zeilen. Ich versuche das anhand eines Beispiels deutlich zu machen

Bsp:

Dataframe X sieht zB folgendermaßen aus:

Spalte 1 Spalte 2 Spalte 3
Zeile 1 A B C
Zeile 2 D E F
Zeile 3 G H I

Dataframe Z sieht zB so aus

Spalte 1 Spalte 2
Zeile 1 1 2
Zeile 2 3 4
Zeile 3 5 6

Angenommen die Spalte 1 von DataFrame Z korreliert stark mit der Spalte des Dataframes y. Deshalb soll die erste Spalte von Z an das Dataframe X angfügt. die zweite Spalte korrliert nicht, deshalb wird sie nicht weiter beachtet


Das was am ende zurückgegeben werden soll ist

Spalte 1 Spalte 2 Spalte 3 Spalte 1
Zeile 1 A B C 1
Zeile 2 D E F 2
Zeile 3 G H I 3

Das muss auch nicht unbedingt als Dataframe zurückgegeben werden soll. Ein np.array wäre auch okay.
Außerdem sollte der Name der Spalte 1 des Dateframes Z im array "self.benutzte_spalten = []" abgespeichert werden


@ Sirus 3

Vielen Dank für die Tipps!

Da die transform Methode nur ein X Argument erwartet wusste ich nicht danke!
Also sollte ich die andern beiden Dataframes dem konstruktor übergeben.

Zu deiner Frage:
ich möchte mit der Klasse zusätzliche Attribute (also die Spalten des Z Dataframes) in mein Feature Dataframe (X Dataframe) aufnehmen, falls diese Features stark mit den Labels (y Dataframe) korrelieren.
Muss ich noch definieren was Features und labels sind oder kennt man das hier schon?

Re: hinzufügen von Spalten an ein array

Verfasst: Sonntag 24. April 2022, 17:33
von nichtSoGuter
ich habe das mit dem code hinbekommen. ich musste wohl nur die methode np.c_ verwenden.
Das ist der fertige Code

Code: Alles auswählen

# neue Spalte nur hinzfügen, wenn die Korrelation zwischen "median_house_value" und dem Attribut größer als 0.25 ist
from scipy import stats
class SpaltenHinzufüger(BaseEstimator, TransformerMixin):
  
    def __init__(self,dataframe_mit_neuen_attributen,y, minimaler_korrelationswert):
        self.name_der_hinzugefügten_spalten=[]
        self.dataframe_mit_neuen_attributen = dataframe_mit_neuen_attributen
        self.y =y
        self.minimaler_korrelationswert = minimaler_korrelationswert
    
    def fit(self,X,y=None):
        pass
    
    def transform(self, X):
        rückgabe = np.array(X)
        for spalten in self.dataframe_mit_neuen_attributen:
            # korrelationen werden berechnet
            spaer_korrelation = stats.spearmanr(self.dataframe_mit_neuen_attributen[spalten],self.y)
            pear_korrelation = stats.pearsonr(self.dataframe_mit_neuen_attributen[spalten],self.y)

             # abhängig von dem Wert der Korrelation wird eine Spalte hinzugefügt
            if(spaer_korrelation.correlation > self.minimaler_korrelationswert or pear_korrelation[0] > self.minimaler_korrelationswert):
                self.name_der_hinzugefügten_Spalten.append(spalten)
                rückgabe= np.c_[rückgabe,self.dataframe_mit_neuen_attributen[spalten]]
        return rückgabe


Re: hinzufügen von Spalten an ein array

Verfasst: Sonntag 24. April 2022, 17:37
von Sirius3
Auch np.c_ ist ineffizient. Die Fehlermeldung passt nicht zum Code, den Du zeigst. `SpaltenHinzufüger` ist die Klasse, die natürlich keine Instanzattribute hat.
`spaltenHinzufüger`, wie in der Fehlermeldung, ist nirgends definiert.

Re: hinzufügen von Spalten an ein array

Verfasst: Sonntag 24. April 2022, 18:41
von nichtSoGuter
Danke für die Antwort!

das ich das attribut nich auf der instnaz aufgerufen habe habe ich erst nach dem posten gemerkt danke.
Was wäre denn effizient?

Vielen Dank im Voraus