Подтвердить что ты не робот

Самый быстрый и наиболее гибкий способ отображать более 2 миллионов строк данных плоского файла?

Я собираю некоторые системные данные в файле flatfile, который имеет этот формат:

YYYY-MM-DD-HH24:MI:SS DD1 DD2 DD3 DD4

Где DD1-DD4 - это четыре элемента данных. Пример файла:

2011-02-01-13:29:53 16 8 7 68
2011-02-01-13:29:58 13 8 6 110
2011-02-01-13:30:03 26 25 1 109
2011-02-01-13:30:08 13 12 1 31
2011-02-01-13:30:14 192 170 22 34
2011-02-01-13:30:19 16 16 0 10
2011-02-01-13:30:24 137 61 76 9
2011-02-01-13:30:29 452 167 286 42
2011-02-01-13:30:34 471 177 295 11
2011-02-01-13:30:39 502 192 309 10

Файл содержит более 2 миллионов строк с точками данных каждые пять секунд.

Мне нужно начертить эти данные, чтобы получить от него смысл.

Что я пробовал

В настоящий момент я пробовал gnuplot и rrdtool с различными инструментами unix (awk, sed и т.д.). Обе эти работы, но, похоже, требуют много измельчения и повторения данных каждый раз, когда я хочу просмотреть его по-другому. Я чувствую, что rrdtool - это правильный путь, но на данный момент я изо всех сил пытаюсь получить данные в этом достаточно быстро, отчасти потому, что мне нужно преобразовать свою временную метку в эпоху Unix. Я также понимаю, что если я решила, что хочу новую гранулярность агрегации, мне нужно перестроить rrd (что имеет смысл для сбора в реальном времени, но не для ретроспективных нагрузок, подобных этому). Эти вещи заставляют меня думать, может быть, я использую неправильный инструмент.

Сбор данных в плоский файл фиксирован - например, я не могу напрямую передать коллекцию в rrdtool.

Мой вопрос

Я бы хотел, чтобы мнения людей касались наилучшего способа создания диаграмм. У меня есть следующие требования:

  • Это должно быть как можно быстрее, чтобы создать график (а не просто визуализировать, но настроить для рендеринга тоже)
  • Он должен быть как можно более гибким - мне нужно гасить вокруг, чтобы графики работали (5 секунд, вероятно, слишком зернистые)
  • Он должен иметь возможность суммировать (MAX/AVG/etc), где необходимо
  • Это должны быть повторяемые и новые файлы данных, поскольку они входят в
  • В идеале я хочу иметь возможность накладывать DD1 на DD2 или DD1 на прошлой неделе с DD1 на этой неделе.
  • Unix или Windows, все равно. Предпочитаю * nix, хотя: -)

Любые предложения?

4b9b3361

Ответ 1

Это действительно хороший вопрос. Я рад видеть, что некоторые люди R взвешивают. Я тоже думаю, что R - правильный инструмент для работы, хотя это мой главный молот, поэтому все выглядит немного как гвоздь для меня.

Существует несколько концепций R, необходимых для решения этой проблемы. Как я вижу, вам нужно следующее (ссылки в parens):

Вот пример кода с использованием 2 мм точек. Если вы заметили, я не проиллюстрирую график всех 2-миллионных точек. Он медленный и не такой информативный. Но это должно дать вам некоторые идеи о начале работы. Не стесняйтесь возвращаться с более конкретными вопросами, если вы решите спрыгнуть в кроличью нору R!

require( xts )
require( lubridate )

## set up some example data
dataLength <- 2e6
startTime <- ymd_hms("2011-02-01-13-29-53")
fistFullOfSeconds <- 1:dataLength
date <- startTime + fistFullOfSeconds
DD1 <- rnorm( dataLength )
DD2 <- DD1 + rnorm(dataLength, 0, .1 )
DD3 <- rnorm( dataLength, 10, 2)
DD4 <- rnorm( dataLength )

myXts <- xts(matrix( c( DD1, DD2, DD3, DD4 ), ncol=4 ), date)

## now all the data are in the myXts object so let do some
## summarizing and visualization

## grabbing just a single day from the data
## converted to data.frame to illustrate default data frame plotting
oneDay <- data.frame( myXts["2011-02-02"] ) 
plot( oneDay )

Отношения между DD1 и DD2-ролями enter image description here

boxplot( oneDay )

Boxplot - это графический фрагмент статистической графики. Сюжет, который вы любите ненавидеть. Также возможно ссылка на это, пока мы здесь. enter image description here

## look at the max value of each variable every minute
par(mfrow=c(4,1)) ## partitions the graph window
ep <- endpoints(myXts,'minutes')
plot(period.apply(myXts[,1],INDEX=ep,FUN=max))
plot(period.apply(myXts[,2],INDEX=ep,FUN=max))
plot(period.apply(myXts[,3],INDEX=ep,FUN=max))
plot(period.apply(myXts[,4],INDEX=ep,FUN=max))

Даже в минуту разрешения я не уверен, что это информативно. Возможно, подмножество. enter image description here

Ответ 2

Здесь некоторый R-код для воспроизведения с 8000000 номерами в 4 столбцах из 2000000 строк:

> d=matrix(runif(8000000),ncol=4)
> dim(d)
[1] 2000000       4
> plot(d[1:1000,1])
> plot(d[1:1000,1],type='l')
> plot(d[1:10000,1],type='l')

теперь он начинает немного замедляться:

> plot(d[1:100000,1],type='l')

как насчет корреляции двух столбцов:

> cor(d[,1],d[,2])
[1] 0.001708502

- мгновенный. Преобразование Фурье?

> f=fft(d[,1])

также мгновенно. Не пытайтесь заговорить, хотя.

Настройте разреженную версию одного из столбцов:

> plot(d[seq(1,2000000,len=1000),1],type='l')

- мгновенный.

То, что действительно отсутствует, - это интерактивный сюжет, где вы можете масштабировать и панорамировать весь набор данных.

Ответ 3

Вот пример по строкам данных, которые у вас есть, загруженные в R, агрегированные и т.д.

Во-первых, некоторые фиктивные данные для записи в файл:

stime <- as.POSIXct("2011-01-01-00:00:00", format = "%Y-%d-%m-%H:%M:%S")
## dummy data
dat <- data.frame(Timestamp = seq(from = stime, by = 5, length = 2000000),
                  DD1 = sample(1:1000, replace = TRUE),
                  DD2 = sample(1:1000, replace = TRUE),
                  DD3 = sample(1:1000, replace = TRUE),
                  DD4 = sample(1:1000, replace = TRUE))
## write it out
write.csv(dat, file = "timestamp_data.txt", row.names = FALSE)

Затем мы можем отсчитывать время в 2-миллионных рядах. Чтобы ускорить это, мы расскажем R о классах столбцов в файле: "POSIXct" является одним из способов в R, чтобы сохранить типы временных меток, которые у вас есть.

## read it in:
system.time({
             tsdat <- read.csv("timestamp_data.txt", header = TRUE,
                                 colClasses = c("POSIXct",rep("integer", 4)))
            })

который занимает около 13 секунд для чтения и форматирования во время внутреннего unix на моем скромном ноутбуке.

   user  system elapsed 
 13.698   5.827  19.643 

Агрегация может быть выполнена множеством способов, один использует aggregate(). Скажем, агрегировать среднее значение часа/среднее значение:

## Generate some indexes that we'll use the aggregate over
tsdat <- transform(tsdat,
                   hours   = factor(strftime(tsdat$Timestamp, format = "%H")),
                   jday    = factor(strftime(tsdat$Timestamp, format = "%j")))
## compute the mean of the 4 variables for each minute
out <- aggregate(cbind(Timestamp, DD1, DD2, DD3, DD4) ~ hours + jday, 
                 data = tsdat, FUN = mean)
## convert average Timestamp to a POSIX time
out <- transform(out,
                 Timestamp = as.POSIXct(Timestamp, 
                                        origin = ISOdatetime(1970,1,1,0,0,0)))

Это (строка, создающая out) занимает около 16 секунд на моем ноутбуке и дает следующий результат:

> head(out)
  hours jday           Timestamp      DD1      DD2      DD3      DD4
1    00  001 2010-12-31 23:29:57 500.2125 491.4333 510.7181 500.4833
2    01  001 2011-01-01 00:29:57 516.0472 506.1264 519.0931 494.2847
3    02  001 2011-01-01 01:29:57 507.5653 499.4972 498.9653 509.1389
4    03  001 2011-01-01 02:29:57 520.4111 500.8708 514.1514 491.0236
5    04  001 2011-01-01 03:29:57 498.3222 500.9139 513.3194 502.6514
6    05  001 2011-01-01 04:29:57 515.5792 497.1194 510.2431 496.8056

Простая компоновка может быть достигнута с помощью функции plot():

plot(DD1 ~ Timestamp, data = out, type = "l")

Мы можем наложить больше переменных через, например:

ylim <- with(out, range(DD1, DD2))
plot(DD1 ~ Timestamp, data = out, type = "l", ylim = ylim)
lines(DD2 ~ Timestamp, data = out, type = "l", col = "red")

или через несколько панелей:

layout(1:2)
plot(DD1 ~ Timestamp, data = out, type = "l", col = "blue")
plot(DD2 ~ Timestamp, data = out, type = "l", col = "red")
layout(1)

Все это было сделано с базовыми функциями R. Другие показали, как дополнительные пакеты могут облегчить работу с датами.