Python pandas:从以空格分隔的“.dat”文件生成文档-术语矩阵
Python pandas: Generate Document-Term matrix from whitespace delimited '.dat' file
我正在使用 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
设法通过更改为列表列表、将列表列表转换为 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()
如果每个文档在文件中只出现一次,您的答案似乎没问题。否则,代码将覆盖 dict d
.
中的某些记录
我认为以下内容更笼统:
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
我正在使用 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
设法通过更改为列表列表、将列表列表转换为 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()
如果每个文档在文件中只出现一次,您的答案似乎没问题。否则,代码将覆盖 dict d
.
我认为以下内容更笼统:
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