根据歌曲评分播放歌曲

根据歌曲评分播放歌曲

0x01 摘要

有若干首歌曲,每首歌曲都有评分(0-10)。现要求做一个歌曲播放功能,每首歌被选到的概率和歌曲评分成正比。比如[{“name”: “真的爱你”, “score”: 9.5}]播放概率/[{“name”: “再见理想”, “score”: 9.2}] 约等于 1.03。作者用python写了一份代码,仅供参考。

0x02 数据存放

歌曲信息数据是类似以下格式存放在musics.txt中:

music_namescore
真的爱你9.5
再见理想9.2
光辉岁月9.3
无尽空虚9.3
不再犹豫9.8
海阔天空9.4
最炫民族风8.5
老鼠爱大米8.4

0x03 方案思路

要求播放歌曲的概率和豆瓣评分成正比,自然想到要将每首歌曲的播放评分和所有歌曲的总评分建立关系,具体来说就是:
歌曲播放概率=歌曲评分/总评分
这就是一种归一化的思想。

0x04 方案实现

在代码中,主要有两个容器:

  • music_dict_list:按类似格式[{“name”: “真的爱你”, “score”: 9.5}]存储的歌曲列表
  • music_score_nom_list:通过计算单手歌曲评分除以总评分归一化后的歌曲概率list

选歌曲的时候用以下代码就能得到和歌曲评分成正比挑选得到的歌曲名称。

np.random.choice(music_dict_list, p=music_score_nom_list)["music_name"]

0x05 测试

循环100万次,用dict分别记录真的爱你再见理想被选中的次数,最后相除得到比值,并保留两位小数且四舍五入,验证比值是否为约等于1.03.

0x06 完整代码

以下是作者自己写的一份简单代码,仅供参考:

import numpy as np
import pandas as pd
from decimal import Decimal

# 1.读取音乐列表
music_info = pd.read_table('musics.txt')
# 2.按格式[{"name": "真的爱你", "score": 9.5}]转换为列表
music_dict_list = music_info.to_dict(orient='records')
# 3.得到评分数组
music_score_array = np.array(music_info.to_dict(orient='list')["score"])
# 4.将得分表归一化
music_score_nom_list = (music_score_array / music_score_array.sum()).tolist()
# 5.代码测试
song_cnt_dict = {'真的爱你':0, '再见理想':0}
for i in range(1000000):
    # 按评分来选歌曲
    song = np.random.choice(music_dict_list, p=music_score_nom_list)["music_name"]
    if song in song_cnt_dict.keys():
        song_cnt_dict[song] += 1

# 循环100万次选歌,真的爱你被选中次数/再见理想被选中次数约为 1.03(保留两位小数且四舍五入)
print(float(Decimal(song_cnt_dict['真的爱你']/song_cnt_dict['再见理想']).quantize(Decimal('0.00'))))

0x07 总结

主要就是采用了概率归一化的思想。

代码里用了:

np.random.choice(music_dict_list, p=music_score_nom_list)

这个函数可以根据概率list来挑选目标list中元素,值得大家学习使用。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值