Pandas: Funktion auf DataFrame anwenden, die mehrere Zeilen zurückgeben kann

Ich versuche, DataFrame zu transformieren, so dass einige der Zeilen eine bestimmte Anzahl von Malen repliziert werden. Beispielsweise:

df = pd.DataFrame({'class': ['A', 'B', 'C'], 'count':[1,0,2]}) class count 0 A 1 1 B 0 2 C 2 

Sollte umgewandelt werden in:

  class 0 A 1 C 2 C 

Dies ist die umgekehrte Aggregation mit Zählfunktion. Gibt es eine einfache Möglichkeit, es in Pandas zu erreichen (ohne Loops oder Listenverständnisse zu benutzen)?

Eine Möglichkeit könnte sein, dass DataFrame.applymap Funktion mehrere Zeilen DataFrame.applymap (verwandte Methode von GroupBy ). Allerdings denke ich nicht, dass es in Pandas jetzt möglich ist.

  • TweepError: Erwartungslänge, unerwarteter Wert gefunden Pandas Jupyter Notebook
  • Python-Pandas: Spalten mit allen Null-Einträgen im Dataframe auswählen
  • Zuordnen mehrerer Dataframe basierend auf den passenden Spalten
  • Begründung über aufeinanderfolgende Datenpunkte ohne Iteration
  • Pandas: Filterung von Pivot-Tabellenzeilen, deren Anzahl kleiner als vorgegebener Wert ist
  • Importieren Sie mehrere CSV-Dateien in Pandas und verknüpfen Sie in einem DataFrame
  • Plotten einer Pandas DataSeries.GroupBy
  • Unbestimmtheit über die Interpolationsfunktion in Pandas
  • 3 Solutions collect form web for “Pandas: Funktion auf DataFrame anwenden, die mehrere Zeilen zurückgeben kann”

    Sie könnten Groupby verwenden:

     def f(group): row = group.irow(0) return DataFrame({'class': [row['class']] * row['count']}) df.groupby('class', group_keys=False).apply(f) 

    So bekommst du

     In [25]: df.groupby('class', group_keys=False).apply(f) Out[25]: class 0 A 0 C 1 C 

    Sie können den Index des Ergebnisses beheben, aber Sie mögen

    Ich weiß, das ist eine alte Frage, aber ich hatte Schwierigkeiten, Wes 'Antwort zu bekommen, um für mehrere Spalten im Dataframe zu arbeiten, also machte ich seinen Code etwas generischer. Dachte, ich würde teilen, falls jemand noch auf diese Frage mit dem gleichen Problem stolpert.

    Sie haben einfach grundsätzlich angeben, welche Spalte die Zählungen darin hat und Sie erhalten ein erweitertes Dataframe im Gegenzug.

     import pandas as pd df = pd.DataFrame({'class 1': ['A','B','C','A'], 'class 2': [ 1, 2, 3, 1], 'count': [ 3, 3, 3, 1]}) print df,"\n" def f(group, *args): row = group.irow(0) Dict = {} row_dict = row.to_dict() for item in row_dict: Dict[item] = [row[item]] * row[args[0]] return pd.DataFrame(Dict) def ExpandRows(df,WeightsColumnName): df_expand = df.groupby(df.columns.tolist(), group_keys=False).apply(f,WeightsColumnName).reset_index(drop=True) return df_expand df_expanded = ExpandRows(df,'count') print df_expanded 

    Kehrt zurück:

      class 1 class 2 count 0 A 1 3 1 B 2 3 2 C 3 3 3 A 1 1 class 1 class 2 count 0 A 1 1 1 A 1 3 2 A 1 3 3 A 1 3 4 B 2 3 5 B 2 3 6 B 2 3 7 C 3 3 8 C 3 3 9 C 3 3 

    In Bezug auf Geschwindigkeit, ist meine Basis df 10 Spalten von ~ 6k Zeilen und wenn erweitert ist ~ 100.000 Zeilen dauert ~ 7 Sekunden. Ich bin mir in diesem Fall nicht sicher, ob Gruppierung notwendig oder weise ist, da es alle Spalten zur Gruppenform nimmt, aber hey, was nur 7 Sekunden.

     repeated_items = [list(row[1]*row[2]) for row in df.itertuples()] 

    Wird eine verschachtelte Liste erstellen:

     [['A'], [], ['C', 'C']] 

    Die Sie dann mit Listenverständnissen umbenennen können, um einen neuen Datenrahmen zu erstellen:

     new_df = pd.DataFrame({"class":[j for i in repeated_items for j in i]}) 

    Natürlich kannst du es auch in einer Zeile machen, wenn du willst:

     new_df = pd.DataFrame({"class":[j for i in [list(row[1]*row[2]) for row in df.itertuples()] for j in i]}) 
    Python ist die beste Programmiersprache der Welt.