我有一个非常大的csv文件,包含大量不同的人。其中一些人出现了两次。像这样:
Name,Colour,Date
John,Red,2017
Dave,Blue,2017
Tom,Blue,2017
Amy,Green,2017
John,Red,2016
Dave,Green,2016
Tom,Blue,2016
John,Green,2015
Dave,Green,2015
Tom,Blue,2015
Rebecca,Blue,2015
我想要一个仅包含每个人最新颜色的csv文件。例如,对于John,Dave,Tom和Amy,我只对2017年的行感兴趣。对于Rebecca,我将需要2015年的价值。
csv文件很庞大,包含超过1000万条记录(所有人都有一个唯一的ID,因此重复的名称无关紧要)。我尝试了以下几点:
Open csv file
Read line 1.
If person is not in "seen" list, add to csv file 2
Add person to "Seen" list.
Read line 2...
问题是“看到”列表变得庞大而我的内存耗尽。另一个问题是有时日期不是有序的,所以旧条目进入“看到”列表,然后新条目不会覆盖它。如果我可以通过降序日期对数据进行排序,这很容易解决,但我很难根据文件的大小对其进行排序。
有什么建议吗?
答案 0 :(得分:0)
如果整个csv文件可以存储在如下列表中:
csv_as_list = [
(unique_id, color, year),
…
]
然后您可以通过以下方式sort
此列表:
import operator
# first sort by year descending
csv_as_list.sort(key=operator.itemgetter(2), reverse=True)
# then, since the Python sort is stable, by unique_id
csv_as_list.sort(key=operator.itemgetter(0))
然后你可以:
from __future__ import print_function
import operator, itertools
for unique_id, group in itertools.groupby(csv_as_list, operator.itemgetter(0)):
latest_color = next(group)[1]
print(unique_id, latest_color)
(我刚刚在这里使用了print
,但你得到了要点。)
如果csv文件无法作为列表加载到内存中,则必须经历使用磁盘的中间步骤(例如SQLite)。
答案 1 :(得分:0)
final_list
。如果找到,请使用您的current_data
数据检查final_list
的年份。如果当前数据包含更新的条目,则只需更改final_list
中用户的日期以及与之关联的颜色。final_list
完成后,你会写一个新的csv文件。如果您希望此任务更快,则需要...
如果仍然没有足够的优化...学习C.在C中读取csv文件,使用分隔符解析它,并且迭代数组并不难,即使在C中也是如此。
答案 2 :(得分:0)
我看到两种明显的解决方法,不涉及在内存中保存大量数据:
使用数据库非常简单。我希望你甚至可以使用Python附带的SQLite。我认为这是我的首选方案。要获得最佳性能,请创建(人,日期)索引。
第二种方法是让CSV文件的第一列为人员ID,第二列为日期。然后,您可以从命令行对CSV文件进行排序,即排序myfile.csv。这会将特定人的所有条目组合在一起,并且如果您的日期是正确的格式(例如YYYY-MM-DD),则感兴趣的条目将是最后一个。 Unix sort命令的速度并不为人所知,但它非常强大。