如何使用Ruby获取大型CSV中列的最后一个元素?

如何使用Ruby获取大型CSV中列的最后一个元素?,ruby,csv,Ruby,Csv,我的CSV大小为30 GB,因此无法打开它。因此,为了找出列的第一行和最后一行,我必须编写一个代码。这是我的代码: require 'csv' COLUMNS = ['timestamp'] i=0 CSV.foreach('C:\Users\hp1\Desktop\Datasets\1433825596_209257.csv', :headers=>true).map do |row| date_column = COLUMNS.map { |col| row[col] }

我的CSV大小为30 GB,因此无法打开它。因此,为了找出列的第一行和最后一行,我必须编写一个代码。这是我的代码:

require 'csv'

COLUMNS = ['timestamp']
i=0
CSV.foreach('C:\Users\hp1\Desktop\Datasets\1433825596_209257.csv', :headers=>true).map do |row|
    date_column = COLUMNS.map { |col| row[col] }
    i=i+1
end
first=date_column(2)
last=date_column(i)
这里我要做的就是将timestamp列存储在数组中,date_列,然后一旦循环退出,打印出前2个,因为它有一个头和数组的最后一个元素。但当我运行它时,它永远不会结束,并且永远保持运行。那么,我的代码出了什么问题?谢谢

使用map意味着您要一次打开整个文件,这是您试图避免的。 不清楚通过迭代列(即['timestamp'])来尝试做什么。 变量i看起来没有用处;如果要访问数组的最后一个元素,可以使用last。 您不能通过执行date_column2来访问数组的元素。 在执行first=date\u column2和last=date\u columni时,您可能会想到一个从1开始的指数化系统。这在编程中很少见。在大多数语言中,索引以0开头,您应该有1和i-1,后者应该不是必需的。 从您试图做的事情来看,您需要在迭代之外初始化date_列。 您的代码可能应该沿着这一行:

file = "C:\Users\hp1\Desktop\Datasets\1433825596_209257.csv"
date_column = []
CSV.foreach(file, headers: true) do |row|
  # Do something with `date_column` and `row`
  #   (Perhaps `push` some elements of `row` into `date_column`
  #   depending on a condition?)
end
first, last = date_column[1], date_column.last

不需要循环计数器、头偏移量、列数组或任何类似的东西。您想要第一个和最后一个值吗?迭代集合并相应地更新当前值

require 'csv'

first_timestamp = nil
last_timestamp = nil

CSV.foreach('C:\Users\hp1\Desktop\Datasets\1433825596_209257.csv', :headers=>true) do |row|
    first_timestamp ||= row['timestamp'] # don't reset it
    last_timestamp = row['timestamp']
end

# do something with the timestamps

我不明白为什么它会永远运行。只是需要很长时间。例如,试着打印i的值。另外,你关于date_列的逻辑对我来说似乎有点奇怪,但它不应该导致无限循环。我让它运行,4小时后返回。它仍然没有停止。生成CSV文件需要4-5个小时,共有42列。那么,考虑到这一点,如果它不能只计算一列中的元素数,你会说这是错误的吗?我想它应该在一个小时内就结束了;它大约有1900-2000万行。还有,我关于date_专栏的逻辑有什么奇怪之处?我对Ruby非常陌生,所以我没有详细研究语法。我使用的是C中的逻辑。有没有更好、更有效的方法来查找Ruby中数组的最后一个元素?逻辑中奇怪的部分是date_列永远不会包含多个项。所以date_列[2]和date_列[i]都将返回nilAh,它在foreach之后有map。是的,这将完全解释永远的部分:如果是我负责这件事,我根本不会费心阅读整个文件。阅读第一行,确定所需列的位置。搜索到文件的近端,在那里找到最后一行。解析并获取所需的值。应该是非常快的。@SergioTulentsev我甚至不清楚OP实际上是指列还是行。问题不清楚啊!!我懂了。但是foreach不是应该像C中的for循环一样,这意味着每次循环运行时,first\u timestamp和last\u timestamp都会得到更新吗?如果没有,foreach如何工作?CSV.foreach和CSV.parse之间有什么区别?非常感谢。由于| |=运算符的原因,第一个_时间戳将只设置一次。确定。但是,当我编写您的程序,并在底部添加puts first_timestamp和puts last_timestamp时,程序不会显示任何内容。为什么会这样?有“timestamp”列吗?你是按原样运行我的代码还是添加了自己的东西?可能是一些函数吧?不,我复制了你的代码。我只在循环外的末端添加了两条puts线。