我有一个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)
答案 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)
首先将所有数据读入内存不是一个好主意。
如何处理如此大的数据文件有两种方法。
流式传输每一行,选择相关信息并解除其余部分,直至EOF。 (参见xml解析器)
对每一行进行流式处理,并将整个数据写入更好的格式,以便您轻松访问相关信息。例如。 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)
它不会将整个文件加载到内存中,而是逐行解析。