2017-12-24 5 views
2

Ich habe eine kleine Funktion, die ich in Pandas ausführen, die einen ValueError löst, wenn ich eine if x in y-Anweisung ausführen. Ich sah ähnlich klingende Probleme, die Boolean Indexing, .isin(), und where() empfehlen, aber ich konnte keines der Beispiele zu meinem Fall anpassen. Jeder Rat würde sehr geschätzt werden.Pandas: Alternative zu Iterrow-Loops

Zusätzlicher Hinweis: groups ist eine Liste von Listen, die Zeichenfolgen außerhalb des Datenrahmens enthalten. Mein Ziel mit der Funktion ist zu sehen, welche Liste ein Element aus dem Datenrahmen enthält, und gibt dann den Index dieser Liste zurück. Meine erste Version davon in dem Notebook-Link unten verwendet iterrows, um den Datenrahmen zu durchlaufen, aber ich verstehe, dass in den meisten Fällen suboptimal ist.

Jupyter Notebook mit einigen gefälschten Daten: https://github.com/amoebahlan61/sturdy-chainsaw/blob/master/Grouping%20Test_1.1.ipynb

Vielen Dank!

Code:

def groupFinder(item): 
    for group in groups: 
     if item in group: 
      return groups.index(group) 

df['groupID2'] = groupFinder(df['item']) 


--------------------------------------------------------------------------- 
ValueError        Traceback (most recent call last) 
<ipython-input-16-808ac3e51e1f> in <module>() 
     4    return groups.index(group) 
     5 
----> 6 df['groupID2'] = groupFinder(df['item']) 

<ipython-input-16-808ac3e51e1f> in groupFinder(item) 
     1 def groupFinder(item): 
     2  for group in groups: 
----> 3   if item in group: 
     4    return groups.index(group) 
     5 

~\AppData\Local\Continuum\anaconda3\lib\site-packages\pandas\core\generic.py in __nonzero__(self) 
    953   raise ValueError("The truth value of a {0} is ambiguous. " 
    954       "Use a.empty, a.bool(), a.item(), a.any() or a.all()." 
--> 955       .format(self.__class__.__name__)) 
    956 
    957  __bool__ = __nonzero__ 

ValueError: The truth value of a Series is ambiguous. Use a.empty, a.bool(), a.item(), a.any() or a.all(). 

Lösung Ich kam in einigen Pandas Blog-Posts und bekam auch ein Feedback von einem reddit Benutzer, die mir eine Lösung gab, die iterrows mithilfe von Pandas' apply Funktion überspringt verwenden.

df['groupID2'] = df.item.apply(groupFinder) 

Vielen Dank für Ihre Hilfe und Antworten.

+0

Im Allgemeinen ist es keine gute Idee, Links zu Daten in Fragen einzufügen - Links können zum einen sterben, zum anderen macht es Ihnen schwerer, Ihnen zu helfen. In diesem Fall wird durch Klicken auf Ihren Link * auch * nicht auf Ihr Notizbuch zugegriffen (obwohl das Kopieren der URL-Zeichenfolge in den Browser funktioniert). Wenn Sie Ihre Frage als Referenz verwenden möchten, ziehen Sie in Erwägung, Ihre Beispieldaten und das Setup in den Text Ihres Posts zu verschieben, als ein [minimales, vollständiges und überprüfbares Beispiel] (https://stackoverflow.com/help/). mcve). –

+0

@andrew_reece Vielen Dank für den Hinweis auf Fragen und Code-Etikette. Ich werde sicher sein, dass das vorwärts geht. –

Antwort

0

Die Art, isin zu verwenden, besteht darin, zuerst Series.isin(...) aufzurufen, um eine boolesche Maske zu erzeugen und dann mit dieser Maske zu indizieren. Alternativ können Sie Ihre Funktion in einer Liste anstelle einer Serie verwenden, um groupFinder(df['item'].values) aufzurufen.

0

IIUC, können Sie tun, was Sie in nur wenigen Zeilen mit Pandas wollen:

import pandas as pd 

# create master list of items 
master = pd.Series(legumesGroup + herbGroup + radishGroup) 

# assign group id as index 
master.index = [0]*len(legumesGroup) + [1]*len(herbGroup) + [2]*len(radishGroup) 

# sample from master with replacement to get itemList 
itemList = master.sample(n=1000, replace=True) 

Jetzt wird in die Gruppe jedes Element in itemList zu bekommen, entweder itemList rufen Sie die Gruppen-ID und Artikel zu sehen, oder einfach itemList.index.

itemList.head() 

Ausgang:

2  Horseradish 
2   Rutabaga 
2    Turnip 
0   Chickpeas 
0  Pinto beans 
+0

Dies ist eine wirklich interessante Lösung. Ich hätte nicht darüber nachgedacht, den Gruppenobjekten einen Indexwert hinzuzufügen. Vielen Dank! –

0

Lösung

Ich kam in einigen Pandas Blog-Posts und bekam auch ein Feedback von einem reddit Benutzer, die mir eine Lösung gegeben, die iterrows überspringt mit unter Verwendung von Pandas 'Funktion anwenden.

df['groupID2'] = df.item.apply(groupFinder) 

Vielen Dank für Ihre Hilfe und Antworten.