pandas, dataframe获取最后一行的三种方法

这次为了做NLP的第一个作业:隐马尔科夫模型的词性判断,开始接触pandas,numpy和pandas我真的很不熟,导致了作业晚交,理解了原理但代码写得很痛苦。

用测试集计算了词性之间的转移概率,转换成矩阵;以及词性到单词的发射概率,转换成矩阵,记得import numpy as np。

veterbi 算法获取预测的词性结果,因为我传进去的观察序列,也就是测试句转换成的单词表,是训练集的每个句子的单词在测试集的单词列表中的对应的索引,所以生成的词性列表就要和传进去的观察序列重新匹配上,才能判断到底预测得对不对。

可把我给难到了,我返回的预测结果是一个矩阵,行的索引是全部训练集里的全部词性,列的索引是每个单词。本来就也不知道怎么做,用了numpy的求每列的最大值的行索引和列索引的方法来返回了一个row, col,其中axis=0是每行,axis=1是每列。row是每列最大值对应的行号组成的列表,col是每列最大值的列号。然后在test_output里新增(单词,词性),有多少个单词新增多少个这样的元组。但是这样的代码可读性太差了,我估计自己第二天来看就看不懂这些col[i]是些什么。

row, col = np.where(np.max(F, axis=0))  # get the max pos for each word
    for i in range(len(obs_seq)):
        test_output.append((obs_seq[col[i]], pi[row[i]]))  # tag index in emission array

然后我又用了第二种办法,把输出矩阵F转换成pandas的dataframe,这个dataframe的行索引还是定义为训练集的全部词性,列索引还是每个单词,但是这样行列就不是123...这种可读性极差的东西了,可以很直观地看出每个单词的词性预测结果里,哪个词性的概率最大。那么我只需要新增一行,表示最大概率的那个数字就可以了。当然要先import pandas哈。其中F是预测结果的矩阵,transitions_probability是转移概率矩阵,emissions_probability是发射概率矩阵,obs_seq是观察序列。F_df是F转换成dataframe。

for sent in test_sents:
    # get the number of total test sentences
    total_count += 1
    #  get expected output of a specific sentence in test set
    expected_output = []
    words_list = []
    for token in sent:
        expected_output.append( (token.get('form'), token.get('upos')) )
        for i in range(len(sorted_words_set)): # get token's index in sorted train_sents words list
            if sorted_words_set[i] == token.get('form'):
                obs_seq.append[i]
                words_list.append(token.get('form'))

    F = viterbi(transitions_probability, emissions_probability, pi, obs_seq)

    F_df = pd.DataFrame(F, index=sorted_tags_set,  columns=words_list , )
F_df.loc['max_idx'] = emission_df.idxmax(axis=0) #求每一列的最大值对应的行索引

然后我要把F_df的列索引,也就是单词列表,和max_idx这一行,也就是每个单词的预测词性这一行一一匹配上。对于怎么取出这一行,我其实试了很多方法,但是都不对,反正是并不困难的事吧,后来直接用最简单的

F_df.values[-1] 取出来了,不需要tolist(),也不要需要astype(str)。之前我查的是,dataframe里字符串是object,但是我需要转成python里的str才能进行迭代(我的代码需要),哎呀然后发现直接用下标访问就可以了,

F_df.values[-1][i]这样就可以。

然后,再记录下另外两种取出最后一行的方法哈:

F_df.tail(1).values.tolist()  这个很简单,但是数据形式是dataframe的,不是我需要的,这里没有用。

F_df.iloc[-1].tolist()

这个其实也可以,通过下标去取的。

你可能感兴趣的:(numpy,机器学习,pandas,机器学习)