Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/string/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 2个数据帧列之间的矢量化/矩阵计算_Python_String_Pandas_Difflib - Fatal编程技术网

Python 2个数据帧列之间的矢量化/矩阵计算

Python 2个数据帧列之间的矢量化/矩阵计算,python,string,pandas,difflib,Python,String,Pandas,Difflib,我使用difflib比率来计算两个字符串之间的相似性: ratio = difflib.SequenceMatcher(None, 'string1', 'string2').ratio() 输出为0-1的单个浮点值,可解释为匹配分数 我要做的是创建一个列,其中包含基于值和其他值列表之间的max(ratio)的最佳匹配 因此,如果: df.col1 = 'maria','fred','john' 以及: df.bestmatch将包含基于df2.col1值的'maria'、'fred'和'j

我使用difflib比率来计算两个字符串之间的相似性:

ratio = difflib.SequenceMatcher(None, 'string1', 'string2').ratio()
输出为0-1的单个浮点值,可解释为匹配分数

我要做的是创建一个列,其中包含基于值和其他值列表之间的
max(ratio)
的最佳匹配

因此,如果:

df.col1 = 'maria','fred','john'
以及:

df.bestmatch
将包含基于
df2.col1
值的
'maria'、'fred'和'john'的最佳匹配

我觉得使用
.apply
方法可以实现这一点,但我就是不知道如何根据
df2.col1
计算
df.col1
中的每个值


更新:difflib.get\u close\u matches方法能够更好地处理大型数组,并提供了我想要的一切,除了比率分数(没什么大不了的)。Tom下面的回答适用于较小的数据集,但当每列的值约为19000时,会出现内存错误。

根据您的评论进行编辑:

In [164]: df = pd.DataFrame({'col1': ['maria','fred','john'], 'col2': ['mary','orange','maria']})
制作所有组合(玛丽亚,玛丽),(玛丽亚,橙色),(玛丽亚,玛丽亚),(弗雷德…)

组合将是一个简单的元组列表,如
('maria','mary')…,
9。因为我们需要每个名称的最佳匹配,所以我们需要根据
col1
中的名称对元组进行分组

In [166]: groups = [list(g) for k, g in itertools.groupby(combos, lambda x: x[0])]
现在我们有三个列表:
[('maria','mary'),('maria','orange'),('maria','maria'),[…]
groupby
的第二个参数是分解组的键。看看这本书

定义辅助函数:

def get_best(group):
    k = group[0][0]
    ratios = {x[1]: difflib.SequenceMatcher(None, *x).ratio() for x in group}
    winner = max(ratios.iteritems(), key=lambda x: x[1])
    return winner[1] # mess with this to return original name, mathcihng name, ratio
这是您将应用于
组中每个列表的函数。就像之前一样,我们将配对的数据交给
SequenceMatcher
以获得比率。只是现在我们需要保留这个名字。所以在这个函数中,
x
是一个类似于
('maria','mary')
的元组。我们需要知道最佳匹配中的名称以及最佳匹配的比率,因此我将它们放入了一个dict中,并带有
{name:ratio}
。这里的另一件事是
max
接受第二个参数。这一次,它只是说要最大化的是比率
x[1]

并获得最佳匹配:

In [173]: best = [get_best(group) for group in groups]

In [175]: df['best_match'] = best

In [176]: df
Out[176]: 
    col1    col2 best_match
0  maria    mary      maria
1   fred  orange     orange
2   john   maria     orange

[3 rows x 3 columns]

这应该是相当有效的。

嘿,汤姆,这让我更接近了——但我想要的是具有最高比率的col2值。例如,maria将根据mary、orange、maria和sam进行评估,然后根据比率得分,maria将被返回。接下来,将根据相同的值对fred进行评估,并返回得分最高的值,依此类推。这有意义吗?这可能可以通过一些丑陋的嵌套for循环来实现,但我希望有一个更优雅/高效的解决方案。哇,这太复杂了。难道没有更简单的方法吗?我对使用90%都不理解的代码感到不舒服……只是添加了一些注释。希望他们能帮忙!也许有一个更简单的方法,但是当你把问题解决的时候,我认为这里的一切都是需要的。首先创建所有匹配项的列表(
组合
)。然后从
df.col1
groups
)按名称将该列表拆分。最后,获取与每个名称最匹配的名称和比率(
get\u best
)。行
[173]
可以使用
df.col1.apply(获得最佳)
完成。嘿,汤姆,我想尝试一下你的解决方案,但在创建groups对象时遇到了一个MemoryError。为了便于参考,每个df列包含大约15000个值……我刚刚发现difflib.get\u close\u matches方法几乎满足了我的需要。
In [167]: groups
Out[167]: 
[[('maria', 'mary'), ('maria', 'orange'), ('maria', 'maria')],
 [('fred', 'mary'), ('fred', 'orange'), ('fred', 'maria')],
 [('john', 'mary'), ('john', 'orange'), ('john', 'maria')]]
def get_best(group):
    k = group[0][0]
    ratios = {x[1]: difflib.SequenceMatcher(None, *x).ratio() for x in group}
    winner = max(ratios.iteritems(), key=lambda x: x[1])
    return winner[1] # mess with this to return original name, mathcihng name, ratio
In [173]: best = [get_best(group) for group in groups]

In [175]: df['best_match'] = best

In [176]: df
Out[176]: 
    col1    col2 best_match
0  maria    mary      maria
1   fred  orange     orange
2   john   maria     orange

[3 rows x 3 columns]