计算两个 pandas DataFrame 的字符串之间的距离
Compute distance between strings of two pandas DataFrames
我有2个数据框:
df1:
Date Name Num
2013-11-24 Banana 22.1
2013-11-24 Orange 8.6
2013-11-24 Apple 7.6
2013-11-24 Celery 10.2
df2:
Date Name Num
2013-11-24 Celery 22.1
2013-11-24 0r@nge 8.6
2013-11-24 @ppl3 7.6
2013-11-24 BananaX 10.2
我想找到相似的行,为此,我现在需要在 2 个数据帧之间找到 Name
的相似度我正在迭代每个数据帧并计算与其他数据的所有其他行的相似度框架(这非常耗时)并找到最大值,如果它大于某个阈值,我将对其进行处理。
dfResult = pd.DataFrame()
import pandas as pd
from fuzzywuzzy import fuzz
for indexD, rowD in dfD.iterrows():
for indexS, rowS in dfS.iterrows():
data = pd.DataFrame({"ratio": fuzz.token_set_ratio(rowD['Name'], rowS['Name']),
"indexD": rowD['Num'], "indexS": rowS['Num']}, index=[indexS])
maxMatch = dfTMP.loc[dfTMP['ratio'].idxmax()]
......
......
......
resultMatch = create_match_row(maxMatch, dfD, dfS)
每次迭代后我得到
indexD 1
indexS 4
ratio 100
Name: 3, dtype: int64
1
indexD 2
indexS 1
ratio 35
Name: 0, dtype: int64
2
indexD 3
indexS 3
ratio 45
Name: 2, dtype: int64
3
indexD 4
indexS 4
ratio 33
Name: 3, dtype: int64
max 函数应该 return :
indexD 1
indexS 4
ratio 100
这意味着数据帧 1 中的第 1 行与数据帧 2 中的第 4 行相似。
我想知道有没有更好的方法可以一次性计算出距离并移除内环?并找到第一个数据框中每一行 (name
) 与第二个数据框的最佳匹配?
预期输出:对于数据框 1 中的每一行,我希望获得显示数据框 2 中哪一行最相同的数据框(只是一个简单的索引)。
IIUIC,这是一种方法
In [3456]: def get_fuzz(df, w):
...: s = df['Name'].apply(lambda y: fuzz.token_set_ratio(y, w))
...: idx = s.idxmax()
...: return {'name': df['Name'].iloc[idx], 'index': idx, 'val': s.max()}
...:
In [3457]: df1['Name'].apply(lambda x: get_fuzz(df2, x))
Out[3457]:
0 {u'index': 3, u'name': u'BananaX', u'val': 92}
1 {u'index': 1, u'name': u'0r@nge', u'val': 67}
2 {u'index': 2, u'name': u'@ppl3', u'val': 67}
3 {u'index': 0, u'name': u'Celery', u'val': 100}
Name: Name, dtype: object
assign
结果为df1
,如果需要
In [3458]: df1.assign(search=df1['Name'].apply(lambda x: get_fuzz(df2, x)))
Out[3458]:
Date Name Num search
0 2013-11-24 Banana 22.1 {u'index': 3, u'name': u'BananaX', u'val': 92}
1 2013-11-24 Orange 8.6 {u'index': 1, u'name': u'0r@nge', u'val': 67}
2 2013-11-24 Apple 7.6 {u'index': 2, u'name': u'@ppl3', u'val': 67}
3 2013-11-24 Celery 10.2 {u'index': 0, u'name': u'Celery', u'val': 100}
详情
In [3459]: df1
Out[3459]:
Date Name Num
0 2013-11-24 Banana 22.1
1 2013-11-24 Orange 8.6
2 2013-11-24 Apple 7.6
3 2013-11-24 Celery 10.2
In [3460]: df2
Out[3460]:
Date Name Num
0 2013-11-24 Celery 22.1
1 2013-11-24 0r@nge 8.6
2 2013-11-24 @ppl3 7.6
3 2013-11-24 BananaX 10.2
我有2个数据框:
df1:
Date Name Num
2013-11-24 Banana 22.1
2013-11-24 Orange 8.6
2013-11-24 Apple 7.6
2013-11-24 Celery 10.2
df2:
Date Name Num
2013-11-24 Celery 22.1
2013-11-24 0r@nge 8.6
2013-11-24 @ppl3 7.6
2013-11-24 BananaX 10.2
我想找到相似的行,为此,我现在需要在 2 个数据帧之间找到 Name
的相似度我正在迭代每个数据帧并计算与其他数据的所有其他行的相似度框架(这非常耗时)并找到最大值,如果它大于某个阈值,我将对其进行处理。
dfResult = pd.DataFrame()
import pandas as pd
from fuzzywuzzy import fuzz
for indexD, rowD in dfD.iterrows():
for indexS, rowS in dfS.iterrows():
data = pd.DataFrame({"ratio": fuzz.token_set_ratio(rowD['Name'], rowS['Name']),
"indexD": rowD['Num'], "indexS": rowS['Num']}, index=[indexS])
maxMatch = dfTMP.loc[dfTMP['ratio'].idxmax()]
......
......
......
resultMatch = create_match_row(maxMatch, dfD, dfS)
每次迭代后我得到
indexD 1
indexS 4
ratio 100
Name: 3, dtype: int64
1
indexD 2
indexS 1
ratio 35
Name: 0, dtype: int64
2
indexD 3
indexS 3
ratio 45
Name: 2, dtype: int64
3
indexD 4
indexS 4
ratio 33
Name: 3, dtype: int64
max 函数应该 return :
indexD 1
indexS 4
ratio 100
这意味着数据帧 1 中的第 1 行与数据帧 2 中的第 4 行相似。
我想知道有没有更好的方法可以一次性计算出距离并移除内环?并找到第一个数据框中每一行 (name
) 与第二个数据框的最佳匹配?
预期输出:对于数据框 1 中的每一行,我希望获得显示数据框 2 中哪一行最相同的数据框(只是一个简单的索引)。
IIUIC,这是一种方法
In [3456]: def get_fuzz(df, w):
...: s = df['Name'].apply(lambda y: fuzz.token_set_ratio(y, w))
...: idx = s.idxmax()
...: return {'name': df['Name'].iloc[idx], 'index': idx, 'val': s.max()}
...:
In [3457]: df1['Name'].apply(lambda x: get_fuzz(df2, x))
Out[3457]:
0 {u'index': 3, u'name': u'BananaX', u'val': 92}
1 {u'index': 1, u'name': u'0r@nge', u'val': 67}
2 {u'index': 2, u'name': u'@ppl3', u'val': 67}
3 {u'index': 0, u'name': u'Celery', u'val': 100}
Name: Name, dtype: object
assign
结果为df1
,如果需要
In [3458]: df1.assign(search=df1['Name'].apply(lambda x: get_fuzz(df2, x)))
Out[3458]:
Date Name Num search
0 2013-11-24 Banana 22.1 {u'index': 3, u'name': u'BananaX', u'val': 92}
1 2013-11-24 Orange 8.6 {u'index': 1, u'name': u'0r@nge', u'val': 67}
2 2013-11-24 Apple 7.6 {u'index': 2, u'name': u'@ppl3', u'val': 67}
3 2013-11-24 Celery 10.2 {u'index': 0, u'name': u'Celery', u'val': 100}
详情
In [3459]: df1
Out[3459]:
Date Name Num
0 2013-11-24 Banana 22.1
1 2013-11-24 Orange 8.6
2 2013-11-24 Apple 7.6
3 2013-11-24 Celery 10.2
In [3460]: df2
Out[3460]:
Date Name Num
0 2013-11-24 Celery 22.1
1 2013-11-24 0r@nge 8.6
2 2013-11-24 @ppl3 7.6
3 2013-11-24 BananaX 10.2