Pandas: merge_asof () Summe mehrere Zeilen / nicht duplizieren

Ich arbeite mit zwei Datensätzen, die unterschiedliche Termine mit jedem verbunden sind. Ich möchte sie zusammenführen, aber weil die Daten nicht exakte Übereinstimmungen sind, glaube ich, dass merge_asof() der beste Weg ist, um zu gehen.

Allerdings passieren zwei Dinge mit einem merge_asof() , die nicht ideal sind:

  1. Zahlen werden dupliziert.
  2. Zahlen sind verloren.

Der folgende Code ist ein Beispiel:

 df_a = pd.DataFrame({'date':pd.to_datetime(['1/15/2016','3/15/2016','5/15/2016','7/15/2016'])}) df_b = pd.DataFrame({'date':pd.to_datetime(['1/1/2016','4/1/2016','5/1/2016','6/1/2016','7/1/2016']), 'num':[1,10,100,1000,10000]}) df_x = pd.merge_asof(df_a, df_b, on = 'date') 

Dies ergibt:

  date num 0 2016-01-15 1 1 2016-03-15 1 2 2016-05-15 100 3 2016-07-15 10000 

Aber stattdessen möchte ich:

  date num 0 2016-01-15 1 1 2016-03-15 0 2 2016-05-15 110 3 2016-07-15 11000 

… wo Sätze von mehreren Zeilen, die zwischen den Daten fallen, addiert werden, und es ist nicht nur die nächste Zeile, die gewählt wird.

Ist das mit merge_asof() oder sollte ich nach einer anderen lösung suchen?

  • Wie man mehrere Dicts mit derselben Taste zusammenführt?
  • Zusammenführen aller SQLite-Datenbanken mit verschiedenen Tabellen
  • Zusammenfassen von zwei tabulatorgetrennten Textdateien um eine gemeinsame Spalte in Python
  • Verwenden von difflib SequenceMatcher-Verhältnis, um in Pandas zu verschmelzen
  • Python-Zusammenführungslisten durch gemeinsames Element
  • Python - Füge zwei Listen mit gleichzeitiger Verknüpfung zusammen
  • Pandas: Fusion auf Spalte von Sammlungen.Counter (oder sogar nur dict) Objekte?
  • Zusammenführen von Dateien auf der Grundlage von Spaltenkoordinaten von zwei Dateien in Python
  • 3 Solutions collect form web for “Pandas: merge_asof () Summe mehrere Zeilen / nicht duplizieren”

    Vielen Dank für die Buchung dieser Frage. Es hat mich dazu veranlasst, ein pädagogisches Paar Stunden zu verbringen, die das merge_asof Quelle merge_asof . Ich glaube nicht, dass Ihre Lösung erheblich verbessert werden kann, aber ich würde ein paar Tweaks anbieten, um es ein paar Prozent zu beschleunigen.

     # if we concat the original date vector, we will only need to merge once df_ax = pd.concat([df_a, df_a.rename(columns={'date':'date1'})], axis=1) # do the outer merge df_m = pd.merge(df_ax, df_b, on='date', how='outer').sort_values(by='date') # do a single rename, inplace df_m.rename(columns={'date': 'datex', 'date1': 'date'}, inplace=True) # fill the gaps to allow the groupby and sum df_m['num'].fillna(0, inplace=True) df_m['date'].fillna(method='bfill', inplace=True) # roll up the results. x = df_m.groupby('date').num.sum().reset_index() 

    Sie bitten um die Zeilen von B, die zwischen der vorherigen und aktuellen Zeile von A. Ich kann den ersten und letzten Index ziemlich leicht mit diesem:

     # get the previous dates from A: prev_dates = np.roll(df_a.date, 1) prev_dates[0] = pd.to_datetime(0) # get the first and last index of B: start = np.searchsorted(df_b.date, prev_dates) stop = np.searchsorted(df_b.date, df_a.date, side='right') - 1 

    Und jetzt kann ich ein kleines Listenverständnis verwenden, um meine Ergebnisse zu erhalten:

     >>> [df_b.num.values[begin:end+1].sum() for begin, end in zip(start, stop)] [1, 0, 110, 11000] 

    Ok, antwortete meine eigene Frage, aber es scheint ein wenig hackish und ich wäre daran interessiert, andere Antworten zu hören. Auch verlässt sich das nicht auf merge_asof() .

    Mit den gleichen DataFrames wie oben:

     df_m = pd.merge(df_a, df_b, on = 'date', how = 'outer').sort_values(by = 'date') df_a = df_a.rename(columns = {'date':'date1'}) df_m = pd.merge(df_m, df_a, left_on = 'date', right_on = 'date1', how = 'outer') df_m['num'].fillna(0, inplace = True) df_m['date1'].fillna(method = 'bfill', inplace = True) x = df_m.groupby('date1').num.sum().reset_index().rename(columns = {'date1':'date'}) 
    Python ist die beste Programmiersprache der Welt.