我有两个不同的文本文件:一个包含单词及其频率,如下所示:
word1<space>frequency
第二个文件首先包含一个单词,后跟其关联的功能。它看起来像:
word1<tab>feature1<tab>feature2................
第二个文件中的每个单词可能包含任意数量的功能(在我的情况下为0-7)
对于文件1中的每个单词,我想要从文件2中与其关联的所有功能。我想创建一个字典,其中键是来自文件1的单词,其对应的值是从文件2获得的功能列表。
此外,我想要独特的功能,并希望消除文件2中的重复项(我还没有实现)。
我有以下代码,但它仅为文件1中的第一个单词提供所需的输出。mydict
确实包含文件1中的所有其他单词,但它们没有任何与之关联的值
mydict = dict()
with open('sample_word_freq_sorted.txt', 'r') as f1:
data = f1.readlines()
with open('sample_features.txt', 'r') as f2:
for item in data:
root = item.split()[0]
mylist = []
for line in f2:
words = line.split()
if words[0] == root:
mylist.append(words[1:])
mydict[root] = mylist
此外,每个键的值是不同的列表,而不仅仅是一个不是我想要的列表。有人可以帮我解决我的代码中的错误吗?
答案 0 :(得分:0)
mydict = dict()
with open('sample_word_freq_sorted.txt', 'r') as f1:
data = set([ line.split()[0] for line in f1])
with open('sample_features.txt', 'r') as f2:
for line in f2:
word = line.split(' ')[0].strip()
if word in data:
mydict[word] = mydict.get(word,[]) + line.split(' ')[1:]
答案 1 :(得分:0)
我认为你最强大的方法是使用Pandas并合并。
df1 = pd.read_csv('sample_word_freq_sorted.txt', delim_whitespace=True)
df2 = pd.read_csv('sample_features.txt', delimeter='\t')
df2 = df2.drop_duplicates()
df = df1.merge(df2, how='left', on='word')
显然,需要针对未发布的数据位进行自定义,但这比尝试在循环中自定义所有内容更不容易出现问题。它还可以轻松处理您的重复问题。
这是否是正确的解决方案还取决于您想要对结果做什么 - 可能在某些情况下让字典版本更好。
编辑:当你的数据没有列标题时,你可以让Pandas给它们起名字,它们是从0开始的整数:
pd.read_csv(path, headers=None)
然后你可以使用整数(例如df [0]将引用名为0的第一列)或稍后更改标题,例如直接指定给df.columns = ['foo', 'bar', baz']
,或者你可以在加载中指定标题:
pd.read_csv(path, names=['foo', 'bar', baz'])
答案 2 :(得分:0)
文件是一个迭代器,意味着你只能迭代一遍:
>>> x = (i for i in range(3)) #example iterator
>>> for line in x:
print(line)
0
1
2
>>> for line in x: #second time produces no results.
print(line)
>>>
因此循环for line in f2:
仅在第一次使用时生成值(for item in data:
的第一次迭代)要修复此问题,您可以执行f2 = f2.readlines()
,这样您就有了一个列表可以遍历多次,或者只用一次f2
的迭代找到构建字典的方法。
然后您会得到一个子列表列表,因为您.append()
的每个单词列表都mylist
,而不是.extend
其他单词,所以只需更改:
mylist.append(words[1:])
到
mylist.extend(words[1:])
应该解决你遇到的其他问题。
这似乎是collections.defaultdict
派上用场的情况,而不是多次遍历文件为每个特定单词添加项目,dict会自动为每个新单词生成空列表,这样可以让你写你的代码是这样的:
import collections
mydict = collections.defaultdict(list)
with open('sample_features.txt', 'r') as f2:
for line in f2:
tmp = line.split()
root = tmp[0]
words = tmp[1:]
#in python 3+ we can use this notation instead of the above three lines:
#root, *words = line.split()
mydict[root].extend(words)
虽然由于您只想保留唯一的功能,但使用set
而不是list
会更有意义,因为它们 - 定义 - 只包含唯一元素,而不是使用{{ 1}}你会使用.extend
:
.update