我得到了两个数据帧,长度为2173的A和长度为6135的B。 A称为“文件名”,B称为“ crsp_name”
A.head()
file_name
0 3M CO
1 ABBOTT LABORATORIES
2 ABC INC
3 ALTRIA GROUP INC
4 AMERICAN ELECTRIC POWER CO
B.head()
0 A & E PLASTIK PAK INC
1 A & M FOOD SERVICES INC
2 A A I CORP
3 A A IMPORTING INC
4 A A R CORP
Name: comnam, dtype: object
我试图计算A中每个元素与B的fuzz.token_set_ratio并将它们组合为一个数据帧。例如,计算“ 3M CO”与B中每个元素的比率,并将“ 3M”与数据帧中最大比例为一行。这样,我有望得到一个shape(2173,2)的数据框
这是我的函数,我尝试使用“ apply”和“ fuzzratio”函数来计算所需的比率。但是出现了错误,希望有人能为我提供正确的解决方案。
def fuzzratio(x):
global crsp_name
ratio_list = list()
name_list = list()
for i in crsp_name:
ratio = fuzz.token_set_ratio(x,i)
if ratio > 80:
name_list.append(x)
ratio_list.append(ratio)
name_list = pd.DataFrame(name_list)
result = pd.merge(name_list,ratio_list).rename(columns = {'comnam','ratio'})
return result
file_name.apply(fuzzratio)
错误:
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "/Library/Frameworks/Python.framework/Versions/3.6/lib/python3.6/site-packages/pandas/core/frame.py", line 6004, in apply
return op.get_result()
File "/Library/Frameworks/Python.framework/Versions/3.6/lib/python3.6/site-packages/pandas/core/apply.py", line 318, in get_result
return super(FrameRowApply, self).get_result()
File "/Library/Frameworks/Python.framework/Versions/3.6/lib/python3.6/site-packages/pandas/core/apply.py", line 142, in get_result
return self.apply_standard()
File "/Library/Frameworks/Python.framework/Versions/3.6/lib/python3.6/site-packages/pandas/core/apply.py", line 248, in apply_standard
self.apply_series_generator()
File "/Library/Frameworks/Python.framework/Versions/3.6/lib/python3.6/site-packages/pandas/core/apply.py", line 277, in apply_series_generator
results[i] = self.f(v)
File "<stdin>", line 11, in fuzzratio
File "/Library/Frameworks/Python.framework/Versions/3.6/lib/python3.6/site-packages/pandas/core/reshape/merge.py", line 60, in merge
validate=validate)
File "/Library/Frameworks/Python.framework/Versions/3.6/lib/python3.6/site-packages/pandas/core/reshape/merge.py", line 526, in __init__
'type {right}'.format(right=type(right)))
ValueError: ("can not merge DataFrame with instance of type <class 'list'>", 'occurred at index file_name')
答案 0 :(得分:0)
我通过以下方式创建测试数据:
dat_A="""file_name
3M CO
ABBOTT LABORATORIES
ABC INC
ALTRIA GROUP INC
AMERICAN ELECTRIC POWER CO"""
dat_B="""crsp_name
A & E PLASTIK PAK INC
A & M FOOD SERVICES INC
A A I CORP
A A IMPORTING INC
A A R CORP
ABBOTT
ABBOTT LABS
ALTRIA
ALTRIA GROUP"""
df_A = pd.read_csv(pd.compat.StringIO(dat_A))
df_B = pd.read_csv(pd.compat.StringIO(dat_B))
由于 df_B 中仅使用 crsp_name 列,以提高效率 我将其提取到 crsp 变量的原因:
crsp = df_B.crsp_name
为便于使用比率阈值进行操作,我将其另存为另一个变量:
ratio_threshold = 50
出于测试目的,我采用了较低的值以获取任何“非空” 结果,但为您的数据将其重新设置为 80 (您定义的值)。
然后我们定义即将应用的功能:
def fn(t1):
ratios = crsp.apply(lambda t2: fuzz.token_set_ratio(t1, t2))
iMax = ratios.idxmax()
rMax = ratios[iMax]
return crsp.loc[iMax] if rMax > ratio_threshold else f'{iMax}_{rMax}'
此功能将应用于 df_A.file_name 中的每个字符串, 因此 t1 是当前值( file_name )。
该函数从计算当前币种之间的令牌集比率开始 文件名和每个 crsp_name (保存在 ratios 中)。
然后将 iMax 计算为最大比率和 rMax 的指数- 最大比例本身。
如果最大比例高于我们的阈值,则该函数返回 相应的 crsp_name 。
否则,该函数将返回“诊断消息”- x_y (2个数字) 其中 x 是找到最大比率的索引, y -比率本身。在程序的最终版本中进行更改 它可以是 np.nan 或一个空字符串。
唯一要做的就是应用此功能并添加结果 作为 df_A 的新列:
df_A['crsp_name'] = df_A.file_name.apply(fn)
对于以上测试数据(阈值== 50),我得到了:
file_name crsp_name
0 3M CO 2_46
1 ABBOTT LABORATORIES ABBOTT
2 ABC INC A & E PLASTIK PAK INC
3 ALTRIA GROUP INC ALTRIA
4 AMERICAN ELECTRIC POWER CO 1_43
如您所见,仍然有2种情况没有职位 crsp_name 中的比率超过了50,但是原因是 源数据非常有限。