Python 仅使用numpy和pandas计算转换矩阵中每个单词的频率

Python 仅使用numpy和pandas计算转换矩阵中每个单词的频率,python,pandas,numpy,matrix,frequency,Python,Pandas,Numpy,Matrix,Frequency,我试图计算转换矩阵中每个单词的频率,仅使用numpy和pandas 我有一根绳子 star_wars = [('darth', 'leia'), ('luke', 'han'), ('chewbacca', 'luke'), ('chewbacca', 'obi'), ('chewbacca', 'luke'), ('leia', 'luke')] 我为这个字符串构建了一个矩阵,使用 现在,我尝试使用以下方法将这些词的值转换为概率: 使用交叉表对初始数据帧有效,但只提供对

我试图计算转换矩阵中每个单词的频率,仅使用numpy和pandas

我有一根绳子

star_wars = [('darth', 'leia'), ('luke', 'han'), ('chewbacca', 'luke'), 
         ('chewbacca', 'obi'), ('chewbacca', 'luke'), ('leia', 'luke')]
我为这个字符串构建了一个矩阵,使用

现在,我尝试使用以下方法将这些词的值转换为概率:

使用交叉表对初始数据帧有效,但只提供对

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)
但它给了我成对的计算(甚至不确定它是否正确)

另一次尝试,只需使用
交叉表

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
期望的关于-具有概率而非数字的矩阵。

比如说

            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

感谢您的时间和帮助

我们仍然可以通过
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

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

df/df.values.sum(轴=1)。重塑(-1,1)) 丘巴卡达斯汉莱娅卢克欧比 丘巴卡0.0.0.0.0 0.666667 0.333333 达斯0.0.0.0 1.0 0.0000000.000000 韩元0.0.0.0.0 1.0000000.000000 莱娅0.0.0.0.0 1.0000000.000000 卢克·楠楠 欧比楠楠楠楠 当然,您应该确保在最后两行中不被零除。 如果行和为零,则该行的所有条目都为零,因此可以用所需的任何内容替换这些行和

>>> 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

非常感谢您的时间和努力!我希望我也能接受你的回答!
>>> 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