【问题标题】:Is it possible to get the number of rows in a CSV file without opening it?是否可以在不打开 CSV 文件的情况下获取行数?
【发布时间】:2015-12-31 00:24:38
【问题描述】:

我有一个大小约为 1 GB 的 CSV 文件,由于我的笔记本电脑是基本配置,我无法在 Excel 或 R 中打开该文件。但出于好奇,我想获取文件中的行。如果我能做到,我该怎么做?

【问题讨论】:

  • 也许只是来自命令行提示符的wc -l yourfile.csv,还是什么?
  • 如果文件大小为 1 GB,您应该可以导入它。当然,你不应该对read.table 和朋友这样做。使用包 data.table 中的fread
  • 所以你是说nrow(read.csv("file.csv", header= T/F)) 会导致 R 崩溃?是的,fread 当然更喜欢
  • @Alex 不要将read.csv 用于 1 GB 文件。很慢。
  • 如果所有方法都崩溃了,您可以使用 csv 拆分器将大文件分成块。不优雅,但可能会工作

标签: r excel csv


【解决方案1】:

对于 Linux/Unix:

wc -l filename

对于 Windows:

find /c /v "A String that is extremely unlikely to occur" filename

【讨论】:

  • 关于“Windows”解决方案,请注意:(1)这是从cmd.exe运行的; (2) filename 包含文件的完整路径(& 将斜线转过来); (3) 如果有标题,则计算该“行”,即标题+ 10 行的文件将导致返回11。 (这些都不会影响答案的质量。)
  • 这不计算CSV中的行数,它计算文件行数,这是不同的。如果您在同一行中有换行符,它们将被单独计算。
【解决方案2】:

选项 1:

通过文件连接,count.fields() 根据一些sep 值(我们在这里不关心)计算文件每行的字段数。因此,如果我们取该结果的长度,理论上我们应该得到文件中的行数(和行数)。

length(count.fields(filename))

如果你有标题行,你可以用skip = 1跳过它

length(count.fields(filename, skip = 1))

您可以根据自己的特定需求调整其他参数,例如跳过空行。

args(count.fields)
# function (file, sep = "", quote = "\"'", skip = 0, blank.lines.skip = TRUE, 
#     comment.char = "#") 
# NULL

请参阅help(count.fields) 了解更多信息。

就速度而言,这还不算太糟糕。我在一个包含 99846 行的棒球文件上对其进行了测试。

nrow(data.table::fread("Batting.csv"))
# [1] 99846

system.time({ l <- length(count.fields("Batting.csv", skip = 1)) })
#   user  system elapsed 
#  0.528   0.000   0.503 

l
# [1] 99846
file.info("Batting.csv")$size
# [1] 6153740

(更高效)选项2:另一个想法是使用data.table::fread() 只读取第一列,然后取行数。这会非常快。

system.time(nrow(fread("Batting.csv", select = 1L)))
#   user  system elapsed 
#  0.063   0.000   0.063 

【讨论】:

  • #option 2 更好。获胜的 data.table。
【解决方案3】:

根据前 1000 行的大小估计行数

size1000  <- sum(nchar(readLines(con = "dgrp2.tgeno", n = 1000)))

sizetotal <- file.size("dgrp2.tgeno")
1000 *  sizetotal / size1000

这对于大多数用途来说通常已经足够了 - 对于大文件来说速度要快得多。

【讨论】:

    【解决方案4】:

    这是我用过的东西:

    testcon <- file("xyzfile.csv",open="r")
    readsizeof <- 20000
    nooflines <- 0
    ( while((linesread <- length(readLines(testcon,readsizeof))) > 0 ) 
    nooflines <- nooflines+linesread )
    close(testcon)
    nooflines
    

    查看这篇文章了解更多信息: https://www.r-bloggers.com/easy-way-of-determining-number-of-linesrecords-in-a-given-large-file-using-r/

    【讨论】:

      【解决方案5】:

      在 R 中实现 Tony 的答案:

      file <- "/path/to/file"
      cmd <- paste("wc -l <", file)
      as.numeric(system(cmd, intern = TRUE))
      

      对于 10 万行的文件,这比 data.table 快大约 4 倍

      >     microbenchmark::microbenchmark(
      +         nrow(fread("~/Desktop/cmx_bool.csv", select = 1L)),
      +         as.numeric(system("wc -l <~/Desktop/cmx_bool.csv", intern = TRUE))
      +     )
      Unit: milliseconds
                                                                     expr       min        lq
                       nrow(fread("~/Desktop/cmx_bool.csv", select = 1L)) 128.06701 131.12878
       as.numeric(system("wc -l <~/Desktop/cmx_bool.csv", intern = TRUE))  27.70863  28.42997
            mean   median        uq      max neval
       150.43999 135.1366 142.99937 629.4880   100
        34.83877  29.5070  33.32973 270.3104   100
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2019-05-30
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2022-11-11
        • 2013-01-07
        • 1970-01-01
        相关资源
        最近更新 更多