【问题标题】:Calculating the frequency of each word in the transition matrix, using numpy and pandas only仅使用 numpy 和 pandas 计算转换矩阵中每个单词的频率
【发布时间】:2020-11-07 18:48:27
【问题描述】:

我正在尝试仅使用 numpy 和 pandas 来计算转换矩阵中每个单词的频率。

我有一个字符串

star_wars = [('darth', 'leia'), ('luke', 'han'), ('chewbacca', 'luke'), 
         ('chewbacca', 'obi'), ('chewbacca', 'luke'), ('leia', 'luke')]

我为这个字符串建立了一个矩阵,使用this question

             chewbacca  darth  han  leia  luke  obi
chewbacca          0      0    0     0     2    1
darth              0      0    0     1     0    0
han                0      0    0     0     1    0
leia               0      0    0     0     1    0
luke               0      0    0     0     0    0
obi                0      0    0     0     0    0

现在我正在尝试使用this question 将这些单词值转换为概率:

使用交叉表适用于初始数据框,但只给我配对

pd.crosstab(pd.Series(star_wars[1:]),
        pd.Series(star_wars[:-1]), normalize = 1)

输出错误,这也不适用于我创建的矩阵,只是一个例子:

col_0   (chewbacca, luke)   (chewbacca, obi)    (darth, leia)   (luke, han)
row_0               
(chewbacca, luke)   0.0 1.0 0.0 1.0
(chewbacca, obi)    0.5 0.0 0.0 0.0
(leia, luke)        0.5 0.0 0.0 0.0
(luke, han)         0.0 0.0 1.0 0.0

我也创建了一个函数

from itertools import islice

def my_function(seq, n = 2):
it = iter(seq)
result = tuple(islice(it, n))
if len(result) == n:
    yield result
for elem in it:
    result = result[1:] + (elem,)
    yield result

应用函数并计算概率

pairs = pd.DataFrame(my_function(star_wars), columns=['Columns', 'Rows'])
counts = pairs.groupby('Columns')['Rows'].value_counts()
probs = (counts/counts.sum()).unstack()

print(probs)

但它给了我对的计算(甚至不确定它是否正确)

Rows               (chewbacca, luke)  (chewbacca, obi)  (leia, luke)  \
Columns                                                                
(chewbacca, luke)                NaN               0.2           0.2   
(chewbacca, obi)                 0.2               NaN           NaN   
(darth, leia)                    NaN               NaN           NaN   
(luke, han)                      0.2               NaN           NaN   

Rows               (luke, han)  
Columns                         
(chewbacca, luke)          NaN  
(chewbacca, obi)           NaN  
(darth, leia)              0.2  
(luke, han)                NaN  

又一次尝试,只用crosstab

想要一个包含概率而非数字的矩阵。

例如

            chewbacca  darth  han  leia  luke  obi
chewbacca          0      0    0     0   0.66 0.33
darth              0      0    0     1     0    0
han                0      0    0     0     1    0
leia               0      0    0     0     1    0
luke               0      0    0     0     0    0
obi                0      0    0     0     0    0

感谢您的时间和帮助!

【问题讨论】:

    标签: python pandas numpy matrix frequency


    【解决方案1】:

    要从转移矩阵中获得概率,您只需将每一行除以行总和即可。

    >>> df / df.values.sum(axis=1).reshape((-1,1))
               chewbacca  darth  han  leia      luke       obi
    chewbacca        0.0    0.0  0.0   0.0  0.666667  0.333333
    darth            0.0    0.0  0.0   1.0  0.000000  0.000000
    han              0.0    0.0  0.0   0.0  1.000000  0.000000
    leia             0.0    0.0  0.0   0.0  1.000000  0.000000
    luke             NaN    NaN  NaN   NaN       NaN       NaN
    obi              NaN    NaN  NaN   NaN       NaN       NaN
    

    当然,您应该确保在最后两行中不要被零除。 如果行总和为零,则该行的所有条目都为零,因此您可以将这些行总和替换为您想要的任何内容。

    >>> row_sums = df.values.sum(axis=1)
    >>> row_sums[row_sums == 0] = 1
    >>> df / row_sums.reshape((-1,1))
               chewbacca  darth  han  leia      luke       obi
    chewbacca        0.0    0.0  0.0   0.0  0.666667  0.333333
    darth            0.0    0.0  0.0   1.0  0.000000  0.000000
    han              0.0    0.0  0.0   0.0  1.000000  0.000000
    leia             0.0    0.0  0.0   0.0  1.000000  0.000000
    luke             0.0    0.0  0.0   0.0  0.000000  0.000000
    obi              0.0    0.0  0.0   0.0  0.000000  0.000000
    

    【讨论】:

    • 非常感谢您的时间和精力!我希望我也能接受你的回答!
    【解决方案2】:

    我们仍然可以通过crosstab 做到这一点

    df=pd.DataFrame(star_wars)
    s=pd.crosstab(df[0],df[1],normalize='index')
    s=s.reindex(index=df.stack().unique(),fill_value=0).reindex(columns=df.stack().unique(),fill_value=0)
    s
    1          darth  leia      luke  han  chewbacca       obi
    0                                                         
    darth          0   1.0  0.000000  0.0          0  0.000000
    leia           0   0.0  1.000000  0.0          0  0.000000
    luke           0   0.0  0.000000  1.0          0  0.000000
    han            0   0.0  0.000000  0.0          0  0.000000
    chewbacca      0   0.0  0.666667  0.0          0  0.333333
    obi            0   0.0  0.000000  0.0          0  0.000000
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2023-03-22
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多