2017-03-20 5 views
0

Ich habe folgenden Pandas Datenrahmen df:Python Pandas verwenden, um mehrere Worte in Spalte als Indizes

Book_Category | Book_Title      | Revenue 
    Thriller  You don't know what I have done  200 
    Romance   Last Summer I loved you    100 

Ich versuche, einen Weg zu finden, einen neuen Datenrahmen, durch Wort im Buch Titel (bitte erstellen beachten Sie, dass Groß- und Kleinschreibung sollte keine Rolle spielen)

Dies ist das Ende Ziel df2:

Book_Title_word | Revenue 
you     300 
I      300 
don't     200 
know     200 
what     200 
have     200 
done     200 
last     100 
summer    100 
loved     100 

Da die Worte, die ich und Sie in beiden Titeln waren, wurden die Einnahmen für sich summieren.

Ist das in Python machbar?

Vielen Dank

UPDATE:

Weil ich größere Zahlen verwenden, wenn die Einnahmen durch A-Za-z in wissenschaftlicher Notation fromat ist vorgesehen mit ('2.155051e-01').

Book_Category | Book_Title      | Revenue | Quantity 
    A    ...what ...       3459283  45757 
    B    what ...        4376899  35657 
    C    .....what       4567856  7689 

df_new = pd.DataFrame(df['Book_Title'].str.split(' ').tolist(), index=df['Revenue']).stack().reset_index()[[0, 'Revenue']] 
df_new.columns = ['Book_Title_word', 'Revenue'] 
df_new.Book_Title_word = df_new.Book_Title_word.str.lower() 

df_new.groupby('Book_Title_word').sum().sort_values(by = 'Revenue',ascending = False) 

Book_Title_word | Revenue 
what     2.160651e-01 

Dies das Problem behoben

pd.set_option('display.float_format', lambda x: '%.3f' % x) 

aus dieser Antwort Format/Suppress Scientific Notation from Python Pandas Aggregation Results

Antwort

1

Hier ist eine Möglichkeit. Teilen Sie den Buchtitel Spalte für Wort einen neuen Datenrahmen

df_new = pd.DataFrame(df['Book_Title'].str.split(' ').tolist(), index=df['Revenue']).stack().reset_index()[[0, 'Revenue']] 
df_new.columns = ['Book_Title_word', 'Revenue'] 
df_new.Book_Title_word = df_new.Book_Title_word.str.lower() 

Jetzt groupby erstellen verwenden, um die Gesamteinnahmen pro jedes Wort

df_new.groupby('Book_Title_word').sum().sort_values(by = 'Revenue',ascending = False) 


       Revenue 
Book_Title_word 
i    300 
you    300 
don't   200 
done   200 
have   200 
know   200 
what   200 
last   100 
loved   100 
summer   100 
+0

danke für diese Antwort - es funktioniert, aber die Zahlen, die ich für den Umsatz bekommen, sind in diesem Format 2.155051e-01- gibt es eine Möglichkeit, das zu vermeiden? Außerdem, wenn ich zwei Metriken addieren möchte - zum Beispiel Revenue und Quantity_bought; kann ich einfach Quantity_bought zum Index hinzufügen? – jeangelj

+0

Können Sie ein Snippet des von Ihnen verwendeten Beispiels bereitstellen? Es wäre einfacher, das Problem zu verstehen – Vaishali

+0

danke - Ich habe ein Beispiel für die Daten hinzugefügt; Ich möchte sowohl Einnahmen als auch Quantität addieren und das wissenschaftliche Notationsformat vermeiden; Kann ich .format() verwenden? – jeangelj

1

Ich bin nicht sicher, ob dies rechnerisch optimal ist (aufgrund einiger quadratischen Forschungen und Lambda-Funktion ...), aber zumindest ist es kurz genug:

new_df = pd.DataFrame({'Book_Title_word': pd.unique(np.concatenate(df.Book_Title.str.lower().str.split()))}) 
new_df['Revenue'] = new_df.Book_Title_word.apply(lambda x: df.loc[df.Book_Title.str.lower().str.contains(x), 'Revenue'].sum()) 

Die erste Zeile erstellt ein neues Datenrahmen mit nur einer Spalte, die durch die Verkettung aller Wörter in den Titeln in Kleinbuchstaben und das Entfernen von Duplikaten gegeben ist. Die zweite Zeile durchläuft dann jedes dieser Elemente und prüft, welche Zeilen einen Titel haben, der (nachdem er in Kleinbuchstaben geschrieben wurde) dieses Wort enthält; Wenn dies der Fall ist, werden alle Ergebnisse zusammengerechnet.

BEARBEITEN: Wie ich durch den Kommentar unten bemerkt habe, funktioniert das Obige nicht, wenn ein Titel Sonderzeichen für Regex enthält, wie *, +, Klammern usw. Daher sollte regex explizit durch Ersetzen der zweiten Zeile ausgeschlossen werden mit:

new_df['Revenue'] = new_df.Book_Title_word.apply(lambda x: df.loc[df.Book_Title.str.lower().str.contains(x, regex=False), 'Revenue'].sum()) 
+0

vielen Dank zu finden - ich folgende Fehlermeldung „Fehler: nichts zu wiederholen "für die zweite Zeile – jeangelj

+0

Mit dem mitgelieferten df habe ich keinen solchen Fehler, vielleicht verwenden Sie andere Daten? Mit Blick auf diesen Thread: http://stackoverflow.com/questions/28606617/pandas-python-regex-error-nothing-to-repeat sieht es so aus, als könnte dies durch eine Regex verursacht werden, in der Tat kann ich den Fehler replizieren einen * oder ein + zu einem Titel. Wie auch immer, es gibt eine einfache Lösung, die ich eigentlich schon haben sollte: Statt 'str.contains (x)', versuche ''str.contains (x, regex = False)'' zu verwenden, um die Verwendung von Regex im Allgemeinen zu vermeiden Allgemein könnten sie versauen, wenn die Titel Sonderzeichen wie *, +, Klammern usw. enthalten. –

+0

Danke- das hat funktioniert – jeangelj

Verwandte Themen