2016-12-29 16 views
0

Я пытаюсь сделать динамическое объединение нечеткой логики для 2 таблиц. То, что я подразумеваю под динамикой, позволяет аргументам указывать переменные, которые позволят двум таблицам присоединиться. код указанный ниже представляет собой модифицированную версию статического кода по следующей ссылке: Python Pandas fuzzy merge/match with duplicatespython dynamic fuzzy logic join

Я скомпилирован динамический код ниже:

import pandas as pd 
import datetime 
from fuzzywuzzy import fuzz 
import difflib 

donors = pd.DataFrame({"name": pd.Series(["John Doe","John Doe","Tom Smith","Jane Doe","Jane Doe","Kat test"]), "Email": pd.Series(['[email protected]','[email protected]','[email protected]','[email protected]','[email protected]','[email protected]']),"Date": (["27/03/2013 10:00:00 AM","1/03/2013 10:39:00 AM","2/03/2013 10:39:00 AM","3/03/2013 10:39:00 AM","4/03/2013 10:39:00 AM","27/03/2013 10:39:00 AM"])}) 
fundraisers = pd.DataFrame({"name": pd.Series(["John Doe","John Doe","Kathy test","Tes Ester", "Jane Doe"]),"Email": pd.Series(['[email protected]','[email protected]','[email protected]','[email protected]','[email protected]']),"Date": pd.Series(["2/03/2013 10:39:00 AM","27/03/2013 11:39:00 AM","3/03/2013 10:39:00 AM","4/03/2013 10:40:00 AM","27/03/2013 10:39:00 AM"])}) 
donors["Date"] = pd.to_datetime(donors["Date"], dayfirst=True) 
fundraisers["Date"] = pd.to_datetime(donors["Date"], dayfirst=True) 
donors["code"] = donors.apply(lambda row: str(row['name'])+' '+str(row['Email']), axis=1) 
idx = donors.groupby('code')["Date"].transform(min) == donors['Date'] 
donors = donors[idx].reset_index().drop('index',1) 

def get_donors_v1(fund_var,don_var, don_tab,row=None): 
    d = don_tab.apply(lambda x: fuzz.ratio(x["%s" % don_var], 'row["%s" %fund_var]') * 2, axis=1) 
    d = d[d >= 75] 
    if len(d) == 0: 
     v = ['']*3 
    else: 
     v = don_tab.ix[d.idxmax(), ["%s"% don_var ,'Email','Date']].values 
    return pd.Series(v, index=['donor name', 'donor email', 'donor date']) 

trial=pd.concat((fundraisers, fundraisers.apply(get_donors_v1(fund_var="name",don_var="name",don_tab=donors), axis=1)), axis=1) 

я получаю следующее сообщение об ошибке:

TypeError: get_donors_v1() takes exactly 4 arguments (3 given)

Следует ли заменить эту функцию на:

get_donors_v1(row=None,fund_var,don_var, don_tab) 

тогда я получаю следующее сообщение об ошибке:

TypeError: ("'NoneType' object has no attribute 'getitem'", u'occurred at index 0')

пожалуйста, помогите.

+1

Я думаю, что значения по умолчанию должны быть размещены в конце, поэтому get_donors_v1 (fund_var, don_var, don_tab, row = None) может сделать трюк? – Guido

+0

Здравствуйте, Гвидо, я попробовал это. Нет помощи :( – Seb

ответ

2

В вашем примере кода вы предоставляете get_donors() со значением None для аргумента 'row'. В следующей строке вы пытаетесь использовать строку в качестве карты (строка ["% s"% fund_var]), не проверяя, существует ли объект, а именно: не равно None.

Индексирование объекта, такого как 'row ["% s"% fund_var]', вызывает вызов метода getitem, который None не имеет.

+0

Я пробовал это. Я не очень хорошо разбираюсь в python. – Seb

+0

Здравствуйте, user508402, я внесла исправление. Я пробовал ваше решение, но получаю этот TypeError: (объект «Series» не может быть вызван », u'occurred at index 0 '). Я участвую в процессе обучения Python - извиняюсь, если мои запросы кажутся педантичными. – Seb

+0

Привет Seb. Ошибка «xxxx is not callable» означает, что объект вызывается как функция, поэтому за его идентификатором следует открывающая скобка. Например: mySeries(). Найдите строку, в которой возникла ваша ошибка, и в этой строке вызывается объект серии. Обратите внимание, что это не должно выглядеть как «pd.Series (...)», для этого является законным конструктором. – user508402