【问题标题】:Python pandas: Generate Document-Term matrix from whitespace delimited '.dat' filePython pandas:从空格分隔的“.dat”文件生成文档项矩阵
【发布时间】:2023-04-09 02:15:02
【问题描述】:

我正在使用 Python 尝试使用 Okapi BM25 model 对文档进行排名。

我认为我可以以更有效的方式计算Score(D,Q) 所需的一些术语,例如 IDF(逆文档频率)(即:计算特定术语(列)的所有非零行) .此外,我可以在矩阵中添加一个新列作为实际分数,然后按此排序以对文档进行排名。

文档术语向量存储在.dat 文件中,其结构如下:

D1 7:10 2:5
D2 1:2 3:4

其中D1 是文档ID,7:10 表示ID 为7 出现10 次的术语

目前,我正在使用以下代码将其读入列表列表:

fname = "dtv.dat"
f = open(fname, "r")
l = [x.strip(" \n").split(" ") for x in f.readlines()]

对于给定的示例产生以下输出:

[['D1', '7:10', '2:5'],['D2' '1:2', '3:4']]

鉴于此列表格式的列表,将其转换为类似于以下内容的 Python pandas DataFrame 的最有效方法是什么:

0      1     2      3      7
D1     0     5      0      10    
D2     2     0      4      0

【问题讨论】:

    标签: python pandas dataframe document


    【解决方案1】:

    如果每个文档在文件中只出现一次,您的答案似乎没问题。否则,代码会覆盖dictd中的一些记录。

    我认为以下内容会更笼统:

    import numpy as np
    import pandas as pd
    
    fname = 'example.txt'
    
    full_list = []
    with open(fname, "r") as f:
        for line in f:
            arr = line.strip(" \n").split(" ")
            for chunk in arr[1:]:
                # converting numbers to ints:
                int_pair = [int(x) for x in chunk.split(":")]
                full_list.append([arr[0], *int_pair])
    
    df = pd.DataFrame(full_list)
    
    df2 = df.pivot_table(values = 2, index = 0, columns = 1, aggfunc = np.sum, fill_value = 0)
    

    它是如何工作的:

    >>> cat 'example.txt'
    D1 1:3 2:2 3:3
    D2 1:4 2:7 
    D2 7:1
    D1 2:4 4:2
    D1 4:1 4:3
    >>> full_list
    Out[37]: 
    [['D1', 1, 3],
     ['D1', 2, 2],
     ['D1', 3, 3],
     ['D2', 1, 4],
     ['D2', 2, 7],
     ['D2', 7, 1],
     ['D1', 2, 4],
     ['D1', 4, 2],
     ['D1', 4, 1],
     ['D1', 4, 3]]
    >>> df
    Out[38]: 
        0  1  2
    0  D1  1  3
    1  D1  2  2
    2  D1  3  3
    3  D2  1  4
    4  D2  2  7
    5  D2  7  1
    6  D1  2  4
    7  D1  4  2
    8  D1  4  1
    9  D1  4  3
    >>> df2
    Out[39]: 
    1   1  2  3  4  7
    0                
    D1  3  6  3  6  0
    D2  4  7  0  0  1
    

    【讨论】:

    • 哇,真的很不错!
    【解决方案2】:

    使用更改为列表列表、将列表列表转换为 ID 字典和词频字典,然后直接转换为 DataFrame 的组合来实现此目的,非常欢迎任何改进!

    def term_matrix(fname):
    f = open(fname, "r")
    l = [x.strip(" \n").split(" ") for x in f.readlines()]
    
    d = dict()
    
    for i in l:
        d[i[0]] = dict(t.split(":") for t in i[1:])
    
    return pd.DataFrame(d).transpose()
    

    【讨论】:

      猜你喜欢
      • 2018-07-18
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多