2013-03-20 34 views
16

Tiêu đề khá tự giải thích ở đây nhưng tôi sẽ giải thích như sau. Một số kỹ thuật hiện tại của tôi trong việc tấn công vấn đề này dựa trên các giải pháp được trình bày trong câu hỏi this. Tuy nhiên, tôi đang phải đối mặt với một số thách thức và khó khăn vì vậy tôi đã tự hỏi nếu ai đó có thể cố gắng để có một đâm vào vấn đề này. Tôi đang cố gắng tìm ra vấn đề bằng cách sử dụng gói bigmemory nhưng tôi đã gặp sự cố.Đọc 40 GB tệp csv thành R bằng bigmemory

ràng buộc hiện tại:

  • Sử dụng một máy chủ Linux với 16 GB RAM
  • Kích thước 40 GB CSV
  • Số hàng: 67.194.126.114

thách thức

  • Cần để có thể lấy mẫu ngẫu nhiên các tập dữ liệu nhỏ hơn (5-10 triệu hàng) từ một big.matrix hoặc cấu trúc dữ liệu tương đương.
  • Cần có khả năng xóa bất kỳ hàng nào bằng một cá thể NULL duy nhất trong khi phân tích cú pháp thành một cấu trúc dữ liệu big.matrix hoặc tương đương.

Cho đến nay, kết quả không tốt. Rõ ràng, tôi đang thất bại tại một cái gì đó hoặc có thể, tôi chỉ không hiểu được bigmemory documentation cũng đủ. Vì vậy, tôi nghĩ rằng tôi sẽ hỏi ở đây để xem có ai đã sử dụng

Bất kỳ mẹo nào, lời khuyên về dòng tấn công này, v.v.? Hay tôi nên đổi sang cái gì khác? Tôi xin lỗi nếu câu hỏi này rất giống với câu hỏi trước nhưng tôi nghĩ theo quy mô dữ liệu lớn hơn khoảng 20 lần so với các câu hỏi trước. Cảm ơn !

+1

Làm thế nào về mẫu nội dung tệp? –

+0

Trường hợp chính xác bạn đang thất bại? Loại dữ liệu nào nằm trong tệp .csv - có phải là tất cả 'double's,' int's hay không? Các mục 'NULL' được thể hiện trong tệp như thế nào? Có tên hàng/cột không? Và, bạn đã thử cái gì? Với một .csv của cấu trúc thích hợp, 'read.big.matrix' sẽ đưa bạn đến đó. –

+0

Thông tin thêm sẽ tốt, nhưng tại sao không nhập nó vào SQL, thực hiện một số chuẩn bị ở đó và sau đó tải nó vào R? –

Trả lời

18

Tôi không biết về bigmemory, nhưng để thỏa mãn những thách thức của bạn, bạn không cần phải đọc tệp. Đơn giản chỉ cần gõ một số bash/awk/sed/python/bất kỳ xử lý nào để thực hiện các bước bạn muốn, tức là ném ra NULL dòng và chọn ngẫu nhiên N dòng và sau đó đọc dòng đó.

Đây là ví dụ sử dụng awk (giả sử bạn muốn 100 dòng ngẫu nhiên từ tệp có 1M dòng).

read.csv(pipe('awk -F, \'BEGIN{srand(); m = 100; length = 1000000;} 
         !/NULL/{if (rand() < m/(length - NR + 1)) { 
           print; m--; 
           if (m == 0) exit; 
           }}\' filename' 
     )) -> df 

Đó là không rõ ràng cho tôi những gì bạn có nghĩa là bởi NULL, vì vậy tôi sử dụng sự hiểu biết nghĩa đen của nó, nhưng nó phải là dễ dàng để sửa đổi nó để phù hợp với nhu cầu của bạn.

+1

Điều này thực sự là một câu trả lời rất tốt và tôi đã giải quyết được vấn đề của tôi đôi khi trở lại bằng cách thực hiện một giải pháp rất giống nhau. Cảm ơn bạn vì câu trả lời này. Tôi sẽ chấp nhận điều này. – Shion

11

Đây là một giải pháp R thuần túy đối với thử thách lấy mẫu từ một tệp văn bản lớn; nó có thành tích bổ sung để vẽ một mẫu ngẫu nhiên chính xác n. Nó không phải là quá không hiệu quả, mặc dù dòng được phân tích cú pháp để vector nhân vật và điều này là tương đối chậm.

Chúng tôi bắt đầu với chữ ký hàm, trong đó chúng tôi cung cấp tên tệp, kích thước của mẫu chúng tôi muốn vẽ, hạt giống cho trình tạo số ngẫu nhiên (để chúng tôi có thể tạo lại mẫu ngẫu nhiên!), Chỉ số cho biết có một dòng tiêu đề, và sau đó một "đầu đọc" chức năng mà chúng ta sẽ sử dụng để phân tích các mẫu vào đối tượng nhìn thấy bởi R, bao gồm lập luận thêm ... rằng chức năng đọc có thể cần

fsample <- 
    function(fname, n, seed, header=FALSE, ..., reader=read.csv) 
{ 

các hạt giống chức năng máy phát điện số ngẫu nhiên, mở ra một kết nối, và đọc trong (không bắt buộc) dòng tiêu đề

set.seed(seed) 
    con <- file(fname, open="r") 
    hdr <- if (header) { 
     readLines(con, 1L) 
    } else character() 

bước tiếp theo là để đọc trong một đoạn của dòng n, khởi tạo một bộ đếm tổng số các dòng được thấy

buf <- readLines(con, n) 
    n_tot <- length(buf) 

Tiếp tục đọc trong khối của dòng n, dừng lại khi không có đầu vào tiếp tục

repeat { 
     txt <- readLines(con, n) 
     if ((n_txt <- length(txt)) == 0L) 
      break 

Đối với mỗi đoạn, vẽ một mẫu n_keep dòng, với số dòng tương ứng với phần của tổng số dòng trong đoạn hiện tại. Điều này đảm bảo rằng các dòng được lấy mẫu thống nhất trên tệp. Nếu không có đường để giữ, hãy di chuyển đến đoạn tiếp theo.

 n_tot <- n_tot + n_txt 
     n_keep <- rbinom(1, n_txt, n_txt/n_tot) 
     if (n_keep == 0L) 
      next 

Chọn dòng giữ lại, và các đường để thay thế, và cập nhật bộ đệm

 keep <- sample(n_txt, n_keep) 
     drop <- sample(n, n_keep) 
     buf[drop] <- txt[keep] 
    } 

Khi nhập dữ liệu được thực hiện, chúng tôi phân tích kết quả bằng cách sử dụng đầu đọc và trả kết quả

reader(textConnection(c(hdr, buf), header=header, ...) 
} 

Giải pháp có thể được thực hiện hiệu quả hơn, nhưng phức tạp hơn một chút, bằng cách sử dụng readBin và tìm kiếm ngắt dòng theo đề xuất của Simon Urbanek trên R-devel mailing list. Đây là giải pháp đầy đủ

fsample <- 
    function(fname, n, seed, header=FALSE, ..., reader = read.csv) 
{ 
    set.seed(seed) 
    con <- file(fname, open="r") 
    hdr <- if (header) { 
     readLines(con, 1L) 
    } else character() 

    buf <- readLines(con, n) 
    n_tot <- length(buf) 

    repeat { 
     txt <- readLines(con, n) 
     if ((n_txt <- length(txt)) == 0L) 
      break 

     n_tot <- n_tot + n_txt 
     n_keep <- rbinom(1, n_txt, n_txt/n_tot) 
     if (n_keep == 0L) 
      next 

     keep <- sample(n_txt, n_keep) 
     drop <- sample(n, n_keep) 
     buf[drop] <- txt[keep] 
    } 

    reader(textConnection(c(hdr, buf)), header=header, ...) 
} 
+0

Cảm ơn bạn đã đăng mã của mình và cảm ơn bạn vì tài liệu tuyệt vời. Bạn sẽ có thể chỉ cho tôi hướng tới và ví dụ bằng cách sử dụng 'readBin'? Cảm ơn! – Zach

Các vấn đề liên quan