目录
一、问题描述
最近跟着莫烦大神的视频学习强化学习(Reinforcement Learning),在敲Q-learning的一个例子的时候,遇到了问题:
二、问题分析
接着来到网上搜寻办法,按照网上的将ix方法替换成iloc或者loc还是报错,我就决定去看看这些方法的使用规则。来到Pandas官网发现DataFrame.ix
这个方法已经被弃用了,本人对于Pandas并不了解,只知道这个方法是用来定位表格数据的。
看完了.loc和.iloc方法后,我大概明白了,它们的使用以及区别:
.loc使用label标签名去定位;并且有类型检查,不兼容会报TypeError;切片包括start和stop;
.iloc使用position(位置)去定位;也有类型检查,不兼容会报TypeError;切片包括start,不包括stop
下面是详细一点的分析过程,不想看的可以跳过这一part,直接跳到三或者四。
- .loc类型检查:使用定义表格时的行名所指定的类型去切片:
- .loc支持的参数
- .iloc支持的参数
三、结合代码解决过程
结合例子中的代码,发现行selector(S)和列selector(A)都是是label,将.ix直接替换成.loc应该就能解决问题了。
题外话:而对于参数中既有label也有position的情况,可以通过label确定position或者通过position确定lable以致于可以使用.loc/.iloc定位,官网也给出了很详细的解决办法,也就是说.ix即可以用.loc替换,也可以用.iloc去替换,只需要使其参数符合要求即可。
按照官网将.ix改成了.loc,发现还是报错,真的是很头大了。但可以确定的一点是参数类型报错,所以我打印输出了例子中的Action,结果,好家伙,按照Q表更新的Action最后来了个1,这就是罪魁祸首,这就要看看.argmax的返回值了......
我上网查了下.argmax的用法,发现它是numpy库里面的方法,正确用法应该是(参考的博客)
对一个一维向量:
import numpy as np
a = np.array([3, 1, 2, 4, 6, 1])
b=np.argmax(a)#取出a中元素最大值所对应的索引,此时最大值位6,其对应的位置索引值为4,(索引值默认从0开始)
print(b)#4
所以它返回的是索引值,而不是对应的列名lable,呜呜呜,搞了半天,结果发现是另一个方法的问题......现在的关键是怎么根据索引值返回列名,罢了,就0和1两个值,干脆不用找pandas里面的方法,自己写个判断就好了。当然对于复杂的情况,比如有表格有很多列,那么就有许多可能的返回值,这个方法就行不通了。
四、最终办法
最后,我把代码改成了这个样子:弃用的方法.ix用.loc代替,再改了下面的代码:
懒人福音:
def choose_action(state, q_table):
# This is how to choose an action
state_actions = q_table.iloc[state, :]
if np.random.uniform() > EPSILON or (state_actions.all() == 0): # act non-greedy or state-action
action_name = np.random.choice(ACTIONS)
# print("随机选择动作:%s" % action_name)
else: # act greedy
action_name = 'right' if state_actions.argmax() else 'left'
# print("根据Q表选择动作:%s" % action_name)
return action_name
故事到这就告一段落了,一杯茶一支烟,一个BUG改一天。当然,是对于我这样的菜鸟而言的,虽然没有什么技术含量,但这就是我解决问题的过程,对于我来说,还是学到了一点东西。大家不想看可以不管,勿喷,谢谢。
五、可以直接跳过废话,看后续!!!!!(重要)
为了防止有和我一样的小伙伴迷路,可以去莫烦大神的github查看更新后的完整源码。不建议采取我的解决办法,而是修改方法: