使用Python解析12GB CSV

时间:2014-05-25 17:51:42

标签: python r csv bigdata

我有一个12 GB的CSV文件。我希望只从这些数据中提取一些列,然后编写一个新的CSV,希望我可以加载到R中进行分析。

问题是我在尝试在写入新CSV文件之前立即加载整个列表时出现内存错误。如何逐行解析数据然后创建CSV输出?

这是我到目前为止所做的:

import pandas

colnames = ['contributor name', 'recipient name', 'recipient party', 'contributor cfscore', 'candidate cfscore', 'amount']

DATA = pandas.read_csv('pathname\filename.csv', names=colnames)
DATA.to_csv(''pathname\filename.csv', cols = colnames)

7 个答案:

答案 0 :(得分:8)

在R中,您可以使用热门data.table package中的fread功能。

您可以使用drop=参数指定不读取的列 - 没有为它们分配内存,并且根本不读取它们。或者select=要保留的列,如果更方便的话。 fread可以非常快速地读取csv文件。

如果您正在处理这么多数据,那么您可能还是想要熟悉data.table包。


或者,sqldf package中的?read.csv.sql表示

  

将文件读入R,使用sql语句对其进行过滤。只有过滤的部分由R处理,以便可以容纳大于R的文件。

以下是例子:

write.csv(iris, "iris.csv", quote = FALSE, row.names = FALSE)
iris2 <- read.csv.sql("iris.csv", 
                      sql="select * from file where Species = 'setosa' ")

答案 1 :(得分:5)

您可以使用csv模块逐行处理文件。这样的事情可能有用:

import csv
infname = "csv.csv"
outfname = "csv_stripped.csv"
cols = ["col1", "col2", "col3"]
with open(infname) as inf, open(outfname, 'w+') as outf:
    reader = csv.DictReader(inf)
    writer = csv.DictWriter(outf, cols, extrasaction='ignore')
    writer.writeheader()
    for line in reader:
        writer.writerow(line)

供参考:

答案 2 :(得分:2)

您不需要python或任何额外的R包来执行此操作。您可以将colClasses参数与R中的数据输入一起使用,以仅读取某些列。为列添加colClasses "NULL"值,以防止在输入过程中加载它。

具有3列的文件(&#34; myfile.csv&#34;)的示例,如果第一列应被视为character,则第三列应被视为integer,并且第二个应该被排除在外:

read.csv("myfile.csv", colClasses=c("character", "NULL", "integer"))

此方法要求您为文件中的每一列指定类。

如果您有很多行,也可能值得在http://stat.ethz.ch/R-manual/R-devel/library/utils/html/read.table.html阅读有关内存使用的建议。

答案 3 :(得分:1)

首先将所有数据读入内存不是一个好主意。

如何处理如此大的数据文件有两种方法。

  1. 流式传输每一行,选择相关信息并解除其余部分,直至EOF。 (参见xml解析器)

  2. 对每一行进行流式处理,并将整个数据写入更好的格式,以便您轻松访问相关信息。例如。 pytables

答案 4 :(得分:1)

如果你有一个函数filter_row,当你想要保留行时返回True,你可以使用:

with open('input.csv') as inp:
    with open('output.csv', 'w') as outp:
        for line in inp:
            if filter_row(line):
                outp.write(line)

答案 5 :(得分:0)

您可以使用R和JDBC实现此目的。让我们创建一个示例csv文件。

write.table(x=mtcars, file="mtcars.csv", sep=",", row.names=F, col.names=T) # create example csv file

从此链接下载并保存CSV JDBC驱动程序:http://sourceforge.net/projects/csvjdbc/files/latest/download,然后设置驱动程序。

> library(RJDBC)

> path.to.jdbc.driver <- "jdbc//csvjdbc-1.0-18.jar"
> drv <- JDBC("org.relique.jdbc.csv.CsvDriver", path.to.jdbc.driver)
> conn <- dbConnect(drv, sprintf("jdbc:relique:csv:%s", getwd())) # replace getwd() with location of csv file

现在您可以撰写查询并选择所需的列,如果需要,可以添加一个where子句来过滤数据,只选择gear取值为5的行:

> dbGetQuery(conn, "select mpg, cyl, gear from mtcars where gear = '5'")
   mpg cyl gear
1   26   4    5
2 30.4   4    5
3 15.8   8    5
4 19.7   6    5
5   15   8    5

答案 6 :(得分:-1)

试试这个:

    file = open("csv.csv", "r")
    for line in file: 
        print(line)

它不会将整个文件加载到内存中,而是逐行解析。