高效python代码持续积累

有时候经常容易忘一些快速的数据实现结构,从此做一些记录。

1. 根据二维数组首元素排序,如下:

data = [[2,3],[5,4],[9,6],[4,7],[8,1]]
data.sort(key=lambda x:x[0])
print(data)
[[2, 3], [4, 7], [5, 4], [8, 1], [9, 6]]

 2.快速去重

def dedupe(items, key=None):
 """
 items: 哈希或者不可哈希的序列
 key: 若items为不可哈希的序列(dict等)则需要指定一个函数
 """
 seen = set()
 for item in items:
     val = item if key is None else key(item)
     if val not in seen:
         yield item
         seen.add(val)

nums = [1,2,32,2,2,4,3,2,3,42]
print(list(dedupe(nums)))
# [1, 2, 32, 4, 3, 42]

students = [
 {"name": "Stanley", "score": 88},
 {"name": "Lily", "score": 92},
 {"name": "Bob", "score": 91},
 {"name": "Well", "score": 80},
 {"name": "Bob", "score": 90},
 {"name": "Peter", "score": 80}
]
deduped_students = list(dedupe(students, key=lambda s: s['name']))
print(deduped_students)
"""
[{'name': 'Stanley', 'score': 88},
{'name': 'Lily', 'score': 92},
{'name': 'Bob', 'score': 91},
{'name': 'Well', 'score': 80},
{'name': 'Peter', 'score': 80}]   # 删除了相同姓名的元素
"""
# 删除姓名和分数都相同的元素
deduped_students = list(dedupe(students, key=lambda s: (s['name'], s['score'])))

 3.jaccar相似度:两个句子分词后词语的交集同词语并集词语数之比

def sim_jaccard(s1, s2):
    """jaccard相似度"""
    s1, s2 = set(s1), set(s2)
    ret1 = s1.intersection(s2)  # 交集
    ret2 = s1.union(s2)  # 并集
    sim = 1.0 * len(ret1) / len(ret2)
    return sim

4.编辑距离相似度:一个句子转换为另一个句子需要的编辑次数,编辑包括:删除、新增、替换,然后使用最长句子的长度归一化得到相似度

def sim_edit(s1, s2):
    """编辑距离归一化后计算相似度"""
    def edit_distance(str1, str2):
        len1, len2 = len(str1), len(str2)
        dp = np.zeros(((len1 + 1, len2 + 1)))
        for i in range(len1 + 1):
            dp[i][0] = i
        for j in range(len2 + 1):
            dp[0][j] = j
        for i in range(1, len1 + 1):
            for j in range(1, len2 + 1):
                temp = 0 if str1[i - 1] == str2[j - 1] else 1
                dp[i][j] = min(dp[i - 1][j - 1] + temp, min(dp[i - 1][j] + 1, dp[i][j - 1] + 1))
        return dp[len1][len2]
    # 1. 计算编辑距离
    res = edit_distance(s1, s2)  
    # 2. 归一化到0~1
    maxLen = max(len(s1), len(s2))  
    sim = 1 - res * 1.0 / maxLen
    return sim

5.simHash相似度:先计算两个句子的simhash二进制编码,使用海明距离计算,最后使用两个句子最大simhash值归一化得到相似度

Hamming Distance,又称汉明距离,在信息论中,两个等长字符串之间的汉明距离是两个字符串对应位置的不同字符的个数。也就是说,它就是将一个字符串变换成另外一个字符串所需要替换的字符个数。例如:1011101 与 1001001 之间的汉明距离是 2。至于我们常说的字符串编辑距离则是一般形式的汉明距离。

from simhash import Simhash
def sim_simhash(s1, s2):
    a_simhash = Simhash(s1, f=64)
    b_simhash = Simhash(s2, f=64)

    # hash值二进制表示形式
    tmp1 = bin(a_simhash.value)
    tmp2 = bin(b_simhash.value)
    max_hashbit = max(len(tmp1), len(tmp2))

    # 计算汉明距离
    distance = a_simhash.distance(b_simhash)
    sim = 1- distance * 1.0 / max_hashbit

    print(sim)

 

posted @ 2020-05-20 09:12  今夜无风  阅读(310)  评论(0编辑  收藏  举报