Как быстро преобразовать строковое значение redis, представляющее собой массив numpy, в кадр данных? - PullRequest
1 голос
/ 17 января 2020

В настоящее время у меня есть программа python, которая выполняет некоторые вычисления временных рядов и отправляет данные в кэш redis. Каждая точка данных представляет собой массив numpy, который выглядит следующим образом:

"[1.18103230e + 07 7.89070000e + 04 -1.88109969e-01 -2.17373938e-01 \ n 1.00433488e + 01 -1.39566174e- 03 -1.95357823e-03 8.36936470e-02 \ n -1.26680427e + 00 -1.85034338e + 00 2.00000000e + 00] "

Затем я хочу, чтобы R вызвал кэш и преобразовал эту строку в фрейм данных или какой-то список. В настоящее время у меня есть это:

    len <- as.numeric(as.character(redisLLen(list)))
    v <- redisLRange(list, 0, len)
    counter <- 1
    for (item in v) {
      item <- strsplit(gsub("(^\\[|\\]$)", "", v), ",")[[counter]]
      item <- strsplit(item, " +")
      df <- rbind(df, item)
      counter <- counter + 1
    }

Это прекрасно работает и нет проблем, но проблема в том, что код R должен работать в режиме реального времени, и это на самом деле очень медленный метод. Есть ли более быстрый способ превратить это значение строки redis в R-фрейм данных? Мы будем благодарны за любую помощь.

ОБНОВЛЕНИЕ:

В моем коде python я убрал квадратные скобки, так что в gsub () в R. было бы меньше удалить. Кроме того, a хороший кусок времени был потрачен на выполнение rbind (). Таким образом, вместо добавления в информационный фрейм, я сделал начальный и вставил элементы. Теперь это точка данных:

"1.18103230e + 07 7.89070000e + 04 -1.88109969e-01 -2.17373938e-01 \ n 1.00433488e + 01 -1.39566174e-03 -1.95357823e-03 8.36936470e -02 \ n -1.26680427e + 00 -1.85034338e + 00 2.00000000e + 00 ",

, и это обновленный код, который я сейчас использую:

    len <- as.numeric(redisLLen(list))
    v <- redisLRange(list, 0, len-1)
    df <- data.frame(matrix(NA, ncol = 8, nrow=len))
    counter <- 1
    for (item in v) {
      item <- unlist(strsplit(item, " +"))
      df[counter, 1:ncol(df)] <- item
      counter <- counter + 1
    } 

1 Ответ

0 голосов
/ 17 января 2020

Если это строка, то мы можем использовать read.table

read.table(text = gsub("[][]", "", v1), header = FALSE, fill = TRUE)
#        V1            V2           V3          V4
#1  1.181032e+07  7.890700e+04 -0.188109969 -0.21737394
#2  1.004335e+01 -1.395662e-03 -0.001953578  0.08369365
#3 -1.266804e+00 -1.850343e+00  2.000000000          NA

или еще быстрее fread

library(data.table)
fread(text = gsub("[][]", "", v1))

Если нам нужен один столбец читать с scan и конвертировать в data.frame

v2 <- scan(text = gsub("[][\n]", "", v1), what = numeric(), quiet = TRUE)
data.frame(col1 = v2)
#           col1
#1   1.181032e+07
#2   7.890700e+04
#3  -1.881100e-01
#4  -2.173739e-01
#5   1.004335e+01
#6  -1.395662e-03
#7  -1.953578e-03
#8   8.369365e-02
#9  -1.266804e+00
#10 -1.850343e+00
#11  2.000000e+00

Или с fread

fread(text = gsub(' ', '\n', gsub("[][]|\n", "", v1)))

Не ясно, как был создан объект. Мы можем конвертировать python объектов в R, используя reticulate

library(reticulate)
np <- import("numpy", convert=FALSE)
np1 <- np$array(c(1.18103230e+07, 7.89070000e+04, -1.88109969e-01, -2.17373938e-01,1.00433488e+01, -1.39566174e-03, -1.95357823e-03, 8.36936470e-02,
     -1.26680427e+00, -1.85034338e+00, 2.00000000e+00))
data.frame(col1 = py_to_r(np1))
#          col1
#1   1.181032e+07
#2   7.890700e+04
#3  -1.881100e-01
#4  -2.173739e-01
#5   1.004335e+01
#6  -1.395662e-03
#7  -1.953578e-03
#8   8.369365e-02
#9  -1.266804e+00
#10 -1.850343e+00
#11  2.000000e+00

data

v1 <- "[ 1.18103230e+07 7.89070000e+04 -1.88109969e-01 -2.17373938e-01\n 1.00433488e+01 -1.39566174e-03 -1.95357823e-03 8.36936470e-02\n -1.26680427e+00 -1.85034338e+00 2.00000000e+00]"
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...