【问题标题】:Create a frequency matrix for bigrams from a list of tuples, using numpy or pandas使用 numpy 或 pandas 从元组列表中为二元组创建频率矩阵
【发布时间】:2020-11-06 19:02:30
【问题描述】:

我对 Python 很陌生。我有一个元组列表,我在其中创建了二元组。

This question 非常接近我的需求

my_list = [('we', 'consider'), ('what', 'to'), ('use', 'the'), ('words', 'of')]

现在我正在尝试将其转换为频率矩阵

想要的输出是

          consider  of  the  to  use  we  what  words
consider         0   0    0   0    0   0     0      0
of               0   0    0   0    0   0     0      0
the              0   0    0   0    0   0     0      0
to               0   0    0   0    0   0     0      0
use              0   0    1   0    0   0     0      0
we               1   0    0   0    0   0     0      0
what             0   0    0   1    0   0     0      0
words            0   1    0   0    0   0     0      0

如何做到这一点,使用numpypandas?不幸的是,我只能看到 nltk 的内容。

【问题讨论】:

    标签: python pandas numpy matrix text


    【解决方案1】:

    您可以创建频率数据框并按单词调用索引值:

    words=sorted(list(set([item for t in my_list for item in t])))
    df = pd.DataFrame(0, columns=words, index=words)
    for i in my_list:
      df.at[i[0],i[1]] += 1
    

    输出:

              consider  of  the  to  use  we  what  words
    consider         0   0    0   0    0   0     0      0
    of               0   0    0   0    0   0     0      0
    the              0   0    0   0    0   0     0      0
    to               0   0    0   0    0   0     0      0
    use              0   0    1   0    0   0     0      0
    we               1   0    0   0    0   0     0      0
    what             0   0    0   1    0   0     0      0
    words            0   1    0   0    0   0     0      0
    

    请注意,在这一个中,二元组的顺序很重要。如果您不关心顺序,则应首先按内容对元组进行排序,使用以下方法:

    my_list = [tuple(sorted(i)) for i in my_list]
    

    另一种方法是使用Counter 进行计数,但我希望它具有相似的性能(同样,如果二元组的顺序很重要,请从frequency_list 中删除sorted):

    from collections import Counter
    
    frequency_list = Counter(tuple(sorted(i)) for i in my_list)
    words=sorted(list(set([item for t in my_list for item in t])))
    df = pd.DataFrame(0, columns=words, index=words)
    for k,v in frequency_list.items():
      df.at[k[0],k[1]] = v
    

    输出:

              consider  of  the  to  use  we  what  words
    consider         0   0    0   0    0   1     0      0
    of               0   0    0   0    0   0     0      1
    the              0   0    0   0    1   0     0      0
    to               0   0    0   0    0   0     1      0
    use              0   0    0   0    0   0     0      0
    we               0   0    0   0    0   0     0      0
    what             0   0    0   0    0   0     0      0
    words            0   0    0   0    0   0     0      0
    

    【讨论】:

    • 感谢您的时间和努力,明天会检查!现在有点晚了!
    【解决方案2】:

    如果你不太关心速度,你可以使用 for 循环。

    import pandas as pd
    import numpy as np
    from itertools import product
    
    my_list = [('we', 'consider'), ('what', 'to'), ('use', 'the'), ('words', 'of')]
    
    index = pd.DataFrame(my_list)[0].unique()
    columns = pd.DataFrame(my_list)[1].unique()
    df = pd.DataFrame(np.zeros(shape=(len(columns), len(index))),
                      columns=columns, index=index, dtype=int)
    
    for idx,col in product(index, columns):
        df[col].loc[idx] = my_list.count((idx, col))
    
    print(df)
    

    输出:

           consider  to  the  of
    we            1   0    0   0
    what          0   1    0   0
    use           0   0    1   0
    words         0   0    0   1
    

    【讨论】:

    • 如果您需要 N x N 稀疏矩阵,则接受的答案会更好。如果您想将矩阵大小保持在绝对最小值并且它不必是对称的,那么这给了您。
    • 我的矩阵很大,10000 * 10000,所以不确定循环是否是个好主意,但我会用你的方法处理更小的矩阵!谢谢!
    猜你喜欢
    • 1970-01-01
    • 2014-12-18
    • 2021-07-26
    • 1970-01-01
    • 2021-01-09
    • 2021-07-20
    • 2018-09-18
    • 2017-03-28
    • 1970-01-01
    相关资源
    最近更新 更多