Schneller Weg, um zu ändern den jeweiligen Wert in dataframe NACH ursprünglichen Wert

Ich habe einen dataframe mit 30000 Spalten und 4000 Zeilen. Jede Zelle Eintrag enthält eine ganze Zahl. Für JEDEN Eintrag, möchte ich multiplizieren Sie den ursprünglichen Inhalt mit log(k/m),

wobei k die Gesamtanzahl der Zeilen, dh.4000 und m ist die Gesamtzahl der nicht-null-Zeilen für die jeweilige SPALTE.

Mein Aktueller code nutzt gelten:

for column in df.columns:
    m = len(df[column].to_numpy().nonzero())
    df[column] = df[column].apply(lambda x: x * np.log10(4000/m))

Dieser nimmt mich Stunden (????). Ich hoffe, es ist etwas schneller Weg, es zu tun, jemand irgendwelche Ideen?

Dank

1 Antworten

  • Dennis Hansen
    4. Mai 2019

    Erzeugen Sie zuerst Beispieldaten:

    np.random.seed(123)
    
    df = pd.DataFrame(np.random.rand(4, 5)*500).astype(int).replace(range(100, 200), 0)
    
    Result:
    
        0   1   2   3   4
    0   348 0   0   275 359
    1   211 490 342 240 0
    2   0   364 219 29  0
    3   368 91  87  265 265
    
    

    Als Nächstes bestimme ich einen Vektor mit den nicht-null-Spalte zählt:

    non_zeros = df.ne(0).sum().values
    
    # Giving me: array([3, 3, 3, 4, 2], dtype=int64)
    

    Von dort aus finde ich den log-Faktor für jede Spalte:

    faktor = np.mat(np.log10(len(df)/ non_zeros))
    
    # giving me: matrix([[0.12493874, 0.12493874, 0.12493874, 0.        , 0.30103   ]])
    
    

    Dann multipliziert jede Spalte mit einem Faktor und der Konvertierung zurück zu DataFrame:

    res = np.multiply(np.mat(df), faktor)
    df = pd.DataFrame(res)