Es wird versucht, 2 Datenrahmen zusammenzuführen, aber ValueError wird abgerufen

79

Dies sind meine beiden Datenrahmen, die in zwei Variablen gespeichert sind:

> print(df.head())
>
          club_name  tr_jan  tr_dec  year
    0  ADO Den Haag    1368    1422  2010
    1  ADO Den Haag    1455    1477  2011
    2  ADO Den Haag    1461    1443  2012
    3  ADO Den Haag    1437    1383  2013
    4  ADO Den Haag    1386    1422  2014
> print(rankingdf.head())
>
           club_name  ranking  year
    0    ADO Den Haag    12    2010
    1    ADO Den Haag    13    2011
    2    ADO Den Haag    11    2012
    3    ADO Den Haag    14    2013
    4    ADO Den Haag    17    2014

Ich versuche, diese beiden mit diesem Code zusammenzuführen:

new_df = df.merge(ranking_df, on=['club_name', 'year'], how='left')

Das how = 'left' wird hinzugefügt, weil ich in meinem Ranking_df weniger Datenpunkte habe als in meinem Standard-df.

Das erwartete Verhalten ist als solches:

> print(new_df.head()) 
> 

      club_name  tr_jan  tr_dec  year    ranking
0  ADO Den Haag    1368    1422  2010    12
1  ADO Den Haag    1455    1477  2011    13
2  ADO Den Haag    1461    1443  2012    11
3  ADO Den Haag    1437    1383  2013    14
4  ADO Den Haag    1386    1422  2014    17

Aber ich bekomme diesen Fehler:

ValueError: Sie versuchen, Objekt- und Int64-Spalten zusammenzuführen. Wenn Sie fortfahren möchten, sollten Sie pd.concat verwenden

Aber ich möchte nicht concat verwenden, da ich die Bäume zusammenführen und nicht nur hinzufügen möchte.

Ein anderes merkwürdiges Verhalten ist, dass mein Code funktioniert, wenn ich die erste df in .csv speichere und diese .csv dann in einen Datenrahmen lade.

Der Code dafür:

df = pd.DataFrame(data_points, columns=['club_name', 'tr_jan', 'tr_dec', 'year'])
df.to_csv('preliminary.csv')

df = pd.read_csv('preliminary.csv', index_col=0)

ranking_df = pd.DataFrame(rankings, columns=['club_name', 'ranking', 'year'])

new_df = df.merge(ranking_df, on=['club_name', 'year'], how='left')

Ich denke, dass es mit dem Parameter index_col = 0 zu tun hat. Aber ich habe keine Ahnung, wie ich es reparieren kann, ohne es speichern zu müssen. Es macht nicht viel aus, aber es ist irgendwie ärgerlich, dass ich das tun muss.

PEREZje
quelle
Ich habe den gleichen Fehler erhalten, wenn ich Join anstelle von Merge verwendet habe.
Modem Rakesh Goud

Antworten:

112

In einem Ihrer Datenrahmen ist das Jahr eine Zeichenfolge und in der anderen ein int64. Sie können es zuerst konvertieren und dann beitreten (z. B. df['year']=df['year'].astype(int)oder wie von RafaelC vorgeschlagen df.year.astype(int)).

Bearbeiten: Beachten Sie auch den Kommentar von Anderson Zhu: Nur für den Fall, dass Sie NoneWerte in einem Ihrer Datenrahmen haben oder fehlen, müssen Sie Int64stattdessen verwenden int. Siehe die Referenz hier .

Arnon Rotem-Gal-Oz
quelle
Danke, es hat funktioniert. Ein bisschen komisch, da ich jedes Jahr als Ints gespart habe.
PEREZje
13
warum nicht df.year.astype(int)?
Rafaelc
Ich habe es schließlich auf eine andere Weise behoben und nur alle Jahresvariablen als Ganzzahlen im Datenrahmen gespeichert. Ich hätte nie gedacht, dass es sich um Saiten handelt.
PEREZje
@ RafaelC das ist wahrscheinlich besser
Arnon Rotem-Gal-Oz
2
Nur für den Fall, dass Sie in einem Ihrer Datenrahmen keine oder fehlende Werte haben, müssen Sie Int64stattdessen verwenden int. Siehe die Referenz hier .
Anderson Zhu
36

Ich stellte fest, dass meine dfs beide den gleichen Typ column ( str) hatten, aber von joinzu wechselten, um mergedas Problem zu lösen.

Alex Moore-Niemi
quelle
5
Hier gilt das gleiche. Wenn jemand weiß warum, schreibe bitte unten :)
raummensch
Gleich. Sehr seltsam, meine einzige Vermutung ist, dass selbst wenn alles vom Typ ist object, beim Ausführen der Join-Pandas versucht wird, die Datentypen noch einmal implizit auszuwerten ... Aber Merge hat es auch für mich gelöst.
15. Schritt
5
@raummensch und @ 15Step, ich hatte das gleiche Problem. Der Grund, warum Merge für Zeichenfolgen funktioniert, Join jedoch nicht, finden Sie in der Antwort von @MatthiasFripp hier: Link . Grundsätzlich wird df1.join(df2)immer über den Index von zusammengeführt, df2während df1.merge(df2)in der Spalte zusammengeführt wird. Im Grunde haben wir versucht, basierend auf einer Zeichenfolge und einer Ganzzahl zusammenzuführen, obwohl beide Spalten Zeichenfolgen waren.
Nicko
3

Es passiert, wenn gemeinsame Spalten in beiden Tabellen unterschiedlichen Datentyps haben.

Beispiel: In Tabelle1 haben Sie Datum als Zeichenfolge, während Sie in Tabelle2 Datum als Datum / Uhrzeit haben. Vor dem Zusammenführen müssen wir das Datum in den allgemeinen Datentyp ändern .

Ashish Anand
quelle
2

@ Arnon Rotem-Gal-Oz Antwort ist größtenteils richtig. Aber ich möchte auf den Unterschied zwischen df['year']=df['year'].astype(int)und hinweisen df.year.astype(int). df.year.astype(int)Gibt eine Ansicht des Datenrahmens zurück und ändert den Typ nicht explizit, zumindest in Pandas 0.24.2. df['year']=df['year'].astype(int)Ändern Sie den Typ explizit, da es sich um eine Zuweisung handelt. Ich würde argumentieren, dass dies der sicherste Weg ist, den dtype einer Spalte dauerhaft zu ändern.

Beispiel:

df = pd.DataFrame({'Weed': ['green crack', 'northern lights', 'girl scout cookies'], 'Qty':[10,15,3]}) df.dtypes

Unkrautobjekt, Menge int64

df['Qty'].astype(str) df.dtypes

Unkrautobjekt, Menge int64

Selbst das Setzen des Inplace-Arg auf True hilft manchmal nicht. Ich weiß allerdings nicht, warum das passiert. In den meisten Fällen entspricht inplace = True einer expliziten Zuweisung.

df['Qty'].astype(str, inplace = True) df.dtypes

Unkrautobjekt, Menge int64

Nun die Aufgabe,

df['Qty'] = df['Qty'].astype(str) df.dtypes

Unkrautobjekt, Mengenobjekt

escha
quelle
1

Zusätzlich: Wenn Sie df im CSV-Format speichern, wird die Datums- und Uhrzeitangabe (in diesem speziellen Fall das Jahr) als Objekt gespeichert. Sie müssen sie daher beim Zusammenführen in eine Ganzzahl (in diesem speziellen Fall das Jahr) konvertieren. Aus diesem Grund können Sie beim Hochladen beider df aus CSV-Dateien die Zusammenführung problemlos durchführen. Der obige Fehler wird angezeigt, wenn eine df aus csv-Dateien und die andere aus einer vorhandenen df hochgeladen wird. Dies ist etwas ärgerlich, hat aber eine einfache Lösung, wenn man bedenkt.

CathyQian
quelle
0

Diese einfache Lösung funktioniert bei mir

    final = pd.concat([df, rankingdf], axis=1, sort=False)

Möglicherweise müssen Sie jedoch zuerst eine doppelte Spalte löschen.

Ega Dharmawan
quelle
0

Überprüfen Sie zunächst den Spaltentyp, den Sie zusammenführen möchten. Sie werden sehen, dass einer von ihnen ein String ist, wo der andere ist int. Konvertieren Sie es dann wie folgt in int:

df["something"] = df["something"].astype(int)

merged = df.merge[df1, on="something"]
Erol Erdogan
quelle