2016-10-23 1 views
0

Ich habe eine Funktion find_country_from_connection_ip, die grundsätzlich eine Pandas-Serie nimmt und nach der Verarbeitung ein Land zurückgibt.Warum AttributeError in DataFrame.apply(), aber nicht in einzelnen Funktionsaufruf auftritt?

def find_country_from_connection_ip(ip): 
    final_output = None 
    result = subprocess.Popen("mmdblookup --file GeoIP2-Country.mmdb --ip {} country names en".format(ip).split(" "), stdout=subprocess.PIPE).stdout.read() 
    if result: 
     final_output = result 
    else: 
     final_output = subprocess.Popen("mmdblookup --file GeoIP2-Country.mmdb --ip {} registered_country names en".format(ip.iloc[0]).split(" "), stdout=subprocess.PIPE).stdout.read() 

    return re.search(r'\"([\w\s]+)\"', final_output).group(1) 

Was ich versuche ist mit dem Rückgabewert der obigen Funktion eine neue Spalte auf meinen Datenrahmen zu bilden. Mein Versuch ist:

dataframe_without_connection_ips['Country'] = 
      dataframe_without_connection_ips.apply(lambda x:find_country_from_connection_ip(x['Connection IP']), axis=1) 

Aber der Fehler ich bin immer ist:

AttributeError: ("'str' object has no attribute 'iloc'", u'occurred at index 303449')

So, sagt mein Verständnis, dass Fehler generiert 303449. von index werden kann, so habe ich versucht, um die Funktion aufzurufen mit diesem bestimmten Index.

test_ip = dataframe_without_connection_ips[dataframe_without_connection_ips.index== 303449]['Connection IP'] 
find_country_from_connection_ip(test_ip) 

Und überraschenderweise Ich erhalte die erwartete Ausgabe 'United Kingdom' ohne Fehler.

Was passiert hier?

Antwort

0

Basierend auf der Art und Weise, wie die Funktion auf Zeilen angewendet wird, ist die Eingabe für die Funktion string. In der Funktion gibt es jedoch diese Operation

, die davon ausgehen, dass die Eingabe eine Serie oder ein DataFrame ist. Dies erklärt die Fehlermeldung.

In Ihrem nachfolgenden Test wird die Eingabe der Funktion tatsächlich zu einer Serie, weshalb die Indexierung iloc nicht fehlschlägt.

+0

Okay, aber sehen Sie, 'ip.iloc [0]' ist in 'else' Klausel. Es wird nur dann ausgeführt, wenn das Argument "ip" keine Zeichenkette ist und so wird "result" zu "False" ausgewertet. Also, ich habe bereits den Fall behandelt, dass ich in einer anderen Klausel eine Serie haben muss. Liege ich falsch? –

+0

Könnte es sein, dass '' result'' in einigen Fällen zu '' False'' führt, auch wenn es sich um eine Zeichenfolge handelt (z. B. eine unerwartete IP-Adresse, die dazu führt, dass die Suche im externen Programm fehlschlägt)? –

Verwandte Themen