2017-12-16 3 views
1

Ich bin relativ neu in Python und Funktionen. Ich versuche, die folgende Funktion durch jede Zeile eines Datenrahmen und hängen das berechnete Ergebnis für jede Zeile zu einer neuen Spalte iterieren:Pandas Iterate-Funktion durch Datenrahmen

def manhattan_distance(x,y): 

    return sum(abs(a-b) for a,b in zip(x,y)) 

als Referenz, ist dies der Datenrahmen Ich teste auf:

entries = [ 
{'age1':'2', 'age2':'2'}, 
{'age1':'12', 'age2': '12'}, 
{'age1':'5', 'age2': '50'} 
] 

df=pd.DataFrame(entries) 

df['age1'] = df['age1'].astype(str).astype(int) 
df['age2'] = df['age2'].astype(str).astype(int) 

ich diese Antwort gesehen habe How to iterate over rows in a DataFrame in Pandas? und haben, soweit dies bekam:

import itertools 
for index, row in df.iterrows(): 

    df['distance']=df.apply(lambda row: manhattan_distance(row['age1'], row['age2']), axis=1) 

Welche gibt die folgende:

-----------------------------------------------------------------------  ---- 
TypeError         Traceback (most recent call last) 
<ipython-input-42-aa6a21cd1de9> in <module>() 
     4 # print (manhattan_distance(row['age1'],row['age2'])) 
     5 
----> 6  df['distance']=df.apply(lambda row: manhattan_distance(row['age1'], row['age2']), axis=1) 

/usr/local/lib/python3.5/dist-packages/pandas/core/frame.py in apply(self, func, axis, broadcast, raw, reduce, args, **kwds) 
    4852       f, axis, 
    4853       reduce=reduce, 
-> 4854       ignore_failures=ignore_failures) 
    4855    else: 
    4856     return self._apply_broadcast(f, axis) 

/usr/local/lib/python3.5/dist-packages/pandas/core/frame.py in _apply_standard(self, func, axis, ignore_failures, reduce) 
    4948    try: 
    4949     for i, v in enumerate(series_gen): 
-> 4950      results[i] = func(v) 
    4951      keys.append(v.name) 
    4952    except Exception as e: 

<ipython-input-42-aa6a21cd1de9> in <lambda>(row) 
     4 # print (manhattan_distance(row['age1'],row['age2'])) 
     5 
----> 6  df['distance']=df.apply(lambda row:  manhattan_distance(row['age1'], row['age2']), axis=1) 

<ipython-input-36-74da75398c4c> in manhattan_distance(x, y) 
     1 def manhattan_distance(x,y): 
     2 
----> 3 return sum(abs(a-b) for a,b in zip(x,y)) 
     4 # return sum(abs(a-b) for a,b in map(lambda x: zip(a,b))) 

TypeError: ('zip argument #1 must support iteration', 'occurred at index 0') 

Basierend auf andere Antworten auf die Frage, die ich oben erwähnt, habe ich die Zip-Anweisung in meiner Funktion zu ändern versucht:

import itertools 
for index, row in df.iterrows(): 

    df['distance']=df.apply(lambda row: manhattan_distance(row['age1'], row['age2']), axis=1) 

Die oben gibt diese:

-------------------------------------------------------------------------- 
TypeError         Traceback (most recent call last) 
<ipython-input-44-aa6a21cd1de9> in <module>() 
     4 # print (manhattan_distance(row['age1'],row['age2'])) 
     5 
----> 6  df['distance']=df.apply(lambda row: manhattan_distance(row['age1'], row['age2']), axis=1) 

/usr/local/lib/python3.5/dist-packages/pandas/core/frame.py in apply(self, func, axis, broadcast, raw, reduce, args, **kwds) 
    4852       f, axis, 
    4853       reduce=reduce, 
-> 4854       ignore_failures=ignore_failures) 
    4855    else: 
    4856     return self._apply_broadcast(f, axis) 

/usr/local/lib/python3.5/dist-packages/pandas/core/frame.py in _apply_standard(self, func, axis, ignore_failures, reduce) 
    4948    try: 
    4949     for i, v in enumerate(series_gen): 
-> 4950      results[i] = func(v) 
    4951      keys.append(v.name) 
    4952    except Exception as e: 

<ipython-input-44-aa6a21cd1de9> in <lambda>(row) 
     4 # print (manhattan_distance(row['age1'],row['age2'])) 
     5 
----> 6  df['distance']=df.apply(lambda row: manhattan_distance(row['age1'], row['age2']), axis=1) 

<ipython-input-43-5daf167baf5f> in manhattan_distance(x, y) 
     2 
     3 # return sum(abs(a-b) for a,b in zip(x,y)) 
----> 4 return sum(abs(a-b) for a,b in map(lambda x: zip(a,b))) 

TypeError: ('map() must have at least two arguments.', 'occurred at index 0') 

Wenn diese ist der richtige Ansatz, ich bin unklar, was meine map() Argumente sein müssen, damit die Funktion funktioniert.

+0

Was wäre die gewünschte Ausgabe? Wie vergleicht man zwei Charaktere? –

+0

Könnten Sie bitte eine Formel zur Berechnung der Manhattan-Entfernung von zwei gegebenen Werten für 'age1' und' age2' angeben. Wie ist der Manhattan-Abstand von zwei Werten definiert, da ich nur Definitionen für mindestens vier Werte finde ... – albert

Antwort

0
import numpy as np 
import pandas as pd 

entries = [ 
{'age1':'2', 'age2':'2'}, 
{'age1':'12', 'age2': '12'}, 
{'age1':'5', 'age2': '50'} 
] 

df = pd.DataFrame(entries) 
df['age1'] = df['age1'].astype(str).astype(int) 
df['age2'] = df['age2'].astype(str).astype(int) 

def manhattan_distance(row): 
    # https://en.wikipedia.org/wiki/Taxicab_geometry#Formal_definition 
    return np.sum(abs(row['age1']-row['age2'])) 

df['distance'] = df.apply(manhattan_distance, axis=1) 
print(df) 
+0

Hier macht es aber keinen Sinn für 'np.sum (..)' da 'abs (..)' nur zurückkommt * ein * Element. –

+0

@ WillemVanOnsem: Du hast Recht. Ich wollte jedoch einen Ansatz für die allgemeine Definition von Manhattan Distance zeigen, der selbst die Differenz von "p_i - q_i" zusammenfassen muss – albert

Verwandte Themen