我正在尝试使用不适合内存的熊猫读取大尺寸的csv文件,并从中创建单词频率,当整个文件都适合内存时,我的代码可以工作,但是定义块大小时却无法检查前面的块,以了解单词是否存在,如果单词不存在,只需增加它的频率即可,只需将其附加到文件末尾即可。不管前面的块里面有什么,它都会单独执行每个块,我正在尝试的代码是
dic = pd.DataFrame()
for chunk in pd.read_csv(fileinput, names=['sentences'], skiprows=skip, chunksize=1):
dic_tmp = (chunk['sentences'].str.split(expand=True).stack().value_counts().rename_axis('word').reset_index(name='freq'))
dic_tmp.append(dic)
dic.to_csv('nenene.csv', index=False, header=None)
出于测试目的,我将chunksize放在了一个小的csv文件中,该文件如下所示:
我得到的输出是:
而我想要得到的是这样的:
我在代码中做错了吗?有什么建议吗?
答案 0 :(得分:1)
我认为您在dic_tmp.append(dic)
上犯了一个错误,您需要的是dic = dic.append(dic_tmp)
。另外,在单词之前,您将在输出中获取熊猫设置的索引,可以在to_csv()函数中使用index=False
参数。
答案 1 :(得分:1)
这是您想做的事情:
chunks = pd.read_csv(fileinput, names=['sentences'], skiprows=skip, chunksize=chunksize)
d = pd.concat(chunks)
d2 = d['sentences'].str.split(expand=True).stack().value_counts().rename_axis('word').reset_index(name='freq')
在读取大文件时避免不必要的循环也会加快代码的速度
答案 2 :(得分:1)
您正在重置每个块中的频率。
您可以为此使用Counter。在开始时创建一个计数器对象。在每个块中,通过其update
方法更新您的计数器。最后,根据需要将counter.most_common()
的输出记录到文件中。
更新: 一个例子是:
import pandas as pd
from collections import Counter
c = Counter([]) # initiate counter with an empty list so we can update it later
chunks = pd.read_csv("/home/emre/Desktop/hdd/foo.csv", chunksize=1)
for chunk in chunks:
for i, row in chunk.iterrows():
c.update(row['sentences'].split(' '))
print(c.most_common())
输出为:
[('fly', 4),
('alex', 2),
('ibrahim', 2),
('hi', 1),
('my', 1),
('name', 1),
('is', 1),
('i', 1),
('am', 1),
('how', 1),
('are', 1),
('you', 1),
('doing', 1)]
现在,您可以遍历最常见的内容并将其保存到文件中
with open('most_commons.txt', 'w+') as f:
for word_freq in c.most_common():
f.write(word_freq[0] + ' ' + str(word_freq[1]) + '\n')
文件:
fly 4
alex 2
ibrahim 2
hi 1
my 1
name 1
is 1
i 1
am 1
how 1
are 1
you 1
doing 1
这样,您就不必制作chunksize=1
。使其像chunksize=1000
一样,这样就不必从磁盘读取文件太多次了。
写文件部分可能写得更优雅;只是为了演示。
答案 3 :(得分:1)
您对使用大熊猫的追求是什么?
也许您可以逐行读取文件并每次更新集合计数器。
import collections
freq = collections.Counter()
with open(filename) as f:
for line in f:
freq.update(line.split())
在此python块之后,您将获得varibale freq中的频率
答案 4 :(得分:1)
您可以简单地按创建的df分组:
输入:
word freq
0 fly 3
1 Alex 1
2 name 1
0 Alex 1
1 fly 1
df.groupby('word').sum()
输出:
freq
word
Alex 2
fly 4
name 1
完整示例:
dic = pd.DataFrame()
for chunk in pd.read_csv(fileinput, names=['sentences'], skiprows=skip, chunksize=1):
dic_tmp = (chunk['sentences'].str.split(expand=True).stack().value_counts().rename_axis('word').reset_index(name='freq'))
dic = dic.append(dic_tmp)
dic = dic.groupby('word').sum().reset_index().sort_values('freq',ascending=False)
dic.to_csv('nenene.csv', index=False, header=None)