[FIXED] Pandas imputieren Werte aus einem gruppierten Datenrahmen in einen anderen Datenrahmen mit einem Objekt

Ausgabe

Für den Datensatz, mit dem ich arbeite, möchte ich Nullwerte mit nach Ländern gruppierten Medianen imputieren. Ich habe eine gruppierte Tabelle (median_data im Code unten) erstellt, die alle Medianwerte nach Land enthält.

Ich muss diese Medianberechnung und Imputation in separaten Schritten durchführen, da das Endziel darin besteht, ein Objekt mit den Methoden „fit“ und „transform“ zu erstellen, damit ich Mediane nur basierend auf den Zugdaten berechnen und den Testdaten zuschreiben kann .

Hier sind Dummy-Daten, mit denen ich arbeite:

data =  [['A', 10, 20, np.nan, np.nan, 50, 30], ['A', 2, 1, 5, np.nan, 34, 35], ['A', 13, 212, 3, 6, np.nan, 37],
         ['B', 120, 230, 53, np.nan, 63, 23], ['B', 22, 115, 15, 61, 4, 15], ['B', np.nan, 22, 12, np.nan, np.nan, 31],
         ['C', 105, 120, np.nan, 22, 520, 3], ['C', 26, 11, 15, np.nan, 34, 3], ['C', 13, np.nan, 13, 234, np.nan, 10],
         ['D', 101, 220, 654, 143, 634, 123], ['D', 32, 21, 61, 24, np.nan, 32], ['D', 11, 72, 23, np.nan, 534, 30]
        ]
df = pd.DataFrame(data, columns=['Country','col1','col2','col3','col4','col5','col6'])


median_data = df.groupby('Country').median().reset_index()

Derzeit kein Objekt verwenden, nur versuchen, herauszufinden, wie es geht. Die Verwendung von Schleifen funktioniert nicht. Ich habe verschiedene Iterationen ausprobiert, hier bin ich gerade:

df_new = df.copy()
for country in median_data.Country:
    country_data = median_data[median_data.Country == country].copy()
    for col in median_data.columns[2:]:
        df_new			
= df_new
.fillna(country_data
)

Der Datensatz, df:

Geben Sie hier die Bildbeschreibung ein

Die Tabelle mit Medianen gruppiert nach „Land“:

Geben Sie hier die Bildbeschreibung ein

Ergebnis aus obigem Code (eindeutig falsch).
Als Beispiel sollte col4 für Land A [6, 6, 6] sein, aber die Werte, die ich bekomme, sind [6, 61, 6]:

Geben Sie hier die Bildbeschreibung ein

Gibt es eine Möglichkeit, Medianwerte separat zu berechnen und zu imputieren? Effizienz ist nicht mein Hauptanliegen, aber eine effiziente Lösung wäre natürlich vorzuziehen.

Update: Obwohl diese Methode anfangs zu funktionieren scheint, erreicht sie nicht das, was ich brauche. Ich muss speziell in der Lage sein, die Medianwerte irgendwie zu speichern und sie dann auch zu verwenden, um sie dem Testsatz zuzuschreiben. Da die Zug- und Testsätze per Definition ungleiche Größen haben, würde die Verwendung von update oder Combine_first nicht funktionieren, da die Zeilennummern nicht übereinstimmen würden und die imputierten Werte falsch wären, selbst wenn die Anzahl der Zeilen irgendwie gleich wäre.

Update 2: Die von @jezrael bereitgestellte Lösung funktioniert, hat aber einen Haken.

median_data = df1.groupby('Country').median()
df2.update(df2[['Country']].merge(median_data, on='Country',  how='left'), overwrite=False)

Dieser Code wird funktionieren, aber zuerst müssen die Indizes der Datensätze mit reset_index(drop=True, inplace=True) zurückgesetzt werden. Das funktioniert vorerst, aber vielleicht bringt das Zurücksetzen von Indizes das Modelltraining usw. durcheinander. Abzuwarten.

Lösung

Verwenden DataFrame.updatemit GroupBy.transformmit median:

df.update(df.groupby('Country').transform('median'), overwrite=False)
print (df)
   Country   col1   col2   col3   col4   col5  col6
0        A   10.0   20.0    4.0    6.0   50.0    30
1        A    2.0    1.0    5.0    6.0   34.0    35
2        A   13.0  212.0    3.0    6.0   42.0    37
3        B  120.0  230.0   53.0   61.0   63.0    23
4        B   22.0  115.0   15.0   61.0    4.0    15
5        B   71.0   22.0   12.0   61.0   33.5    31
6        C  105.0  120.0   14.0   22.0  520.0     3
7        C   26.0   11.0   15.0  128.0   34.0     3
8        C   13.0   65.5   13.0  234.0  277.0    10
9        D  101.0  220.0  654.0  143.0  634.0   123
10       D   32.0   21.0   61.0   24.0  584.0    32
11       D   11.0   72.0   23.0   83.5  534.0    30

Einzelheiten :

print (df.groupby('Country').transform('median'))
    col1   col2  col3   col4   col5  col6
0   10.0   20.0   4.0    6.0   42.0    35
1   10.0   20.0   4.0    6.0   42.0    35
2   10.0   20.0   4.0    6.0   42.0    35
3   71.0  115.0  15.0   61.0   33.5    23
4   71.0  115.0  15.0   61.0   33.5    23
5   71.0  115.0  15.0   61.0   33.5    23
6   26.0   65.5  14.0  128.0  277.0     3
7   26.0   65.5  14.0  128.0  277.0     3
8   26.0   65.5  14.0  128.0  277.0     3
9   32.0   72.0  61.0   83.5  584.0    32
10  32.0   72.0  61.0   83.5  584.0    32
11  32.0   72.0  61.0   83.5  584.0    32

Alternative Lösung mit DataFrame.combine_first:

df1 = df.combine_first(df.groupby('Country').transform('median'))
print (df1)
   Country   col1   col2   col3   col4   col5  col6
0        A   10.0   20.0    4.0    6.0   50.0    30
1        A    2.0    1.0    5.0    6.0   34.0    35
2        A   13.0  212.0    3.0    6.0   42.0    37
3        B  120.0  230.0   53.0   61.0   63.0    23
4        B   22.0  115.0   15.0   61.0    4.0    15
5        B   71.0   22.0   12.0   61.0   33.5    31
6        C  105.0  120.0   14.0   22.0  520.0     3
7        C   26.0   11.0   15.0  128.0   34.0     3
8        C   13.0   65.5   13.0  234.0  277.0    10
9        D  101.0  220.0  654.0  143.0  634.0   123
10       D   32.0   21.0   61.0   24.0  584.0    32
11       D   11.0   72.0   23.0   83.5  534.0    30


Beantwortet von –
jezrael


Antwort geprüft von –
Marilyn (FixError Volunteer)

0 Shares:
Leave a Reply

Your email address will not be published. Required fields are marked *

You May Also Like