繁体   English   中英

从 R data.table 到 python 访问数据的推荐方式是什么? 我可以避免将数据写入光盘吗?

[英]What is the recommended way to access data from R data.table in python? Can I avoid writing data to disc?

是否有一些推荐的方法可以将数据从 R (以data.table的形式)传递到 Python 而无需将数据保存到光盘? 我知道我可以使用reticulate使用 R 中的 python 模块(我想同样的事情可以在另一侧使用rpy2 ),但从我读过的内容来看,这会损害库的整体性能,因此有相当多的最好将我的 r data.table存储到光盘并使用 python 并运行lightgbm从光盘读取相同的数据,而不是尝试使用reticulate运行lightgbm或使用data.table运行 data.table。

为什么我不坚持使用 R 或 Python

我更喜欢使用 r data.table (相对于Pandas )进行数据操作,因为它速度更快,效率更高 memory 并且具有很多我喜欢的功能,例如不等式连接、滚动连接、笛卡尔连接,而且非常简单熔炼和铸造。 我也喜欢每当我在堆栈溢出中询问data.table相关问题时,我都能很快得到高质量的答案,而对于Pandas ,我并没有那么成功。 但是,有些任务我更喜欢 python,例如梯度提升或神经网络。

没有推荐的方法。

理论上你必须将 R data.frame 转储到磁盘并在 python 中读取它。

在实践中(假设生产级操作系统),您可以使用“RAM 磁盘”位置/dev/shm/因此您实际上将数据写入驻留在 RAM memory 中的文件,然后直接从 RAM 中读取它,而无需转储数据到磁盘 memory。

用法示例:

fwrite(iris, "/dev/shm/data.csv")
d = fread("/dev/shm/data.csv")
unlink("/dev/shm/data.csv")

至于格式,您有以下选择:

  1. csv - 通用和便携格式

data.tablefwrite function 速度超快,生成可移植的 csv 数据文件。 在多核机器上使用fwrite之前,请务必使用setDTthreads(0L)启用所有 cpu 线程。

然后在 python 你需要读取 csv 文件,为此datatable数据表模块将非常快,然后,如果需要,可以使用x.to_pandas()将 object 转换为 python pandas

  1. feather - “便携”二进制格式

另一种选择是使用 R 的arrow package 和 function write_feather ,然后使用pyarrow模块和read_feather读取 python 中的数据。

在大多数情况下,此格式应该比 csv 更快,请参阅下面的时序。 在写入数据的情况下,差异可能不会那么大,但在大多数情况下读取数据会快得多,尤其是在读取 R 中的许多字符变量时(尽管这不是您的用例,因为您是在 python 中读取的)。 另一方面,它还不是真正可移植的(参见apache/arrow#8732 )。 此外,如果最终发布新版本 3,则使用当前 feather 保存的文件可能不再兼容。

  1. fst - 快速二进制格式

fst可以用作 feather 格式的更快替代品,但尚无法读取 python 中的 fst 数据,因此目前无法应用此方法来解决您的问题。 您可以在https://github.com/fstpackage/fst/issues/184跟踪这个 FR 的进度,当问题解决时,它可能会以最快的方式解决您的问题。


使用以下脚本

library(data.table)
setDTthreads(0L) ## 40

N = 1e8L
x = setDT(lapply(1:10, function(...) sample.int(N)))
system.time(arrow::write_feather(x, "/dev/shm/data.feather"))
system.time(fwrite(x, "/dev/shm/data.csv", showProgress=FALSE))
rm(x)
## run python

unlink(paste0("/dev/shm/data.",c("csv","feather")))
N = 1e8L
x = setDT(lapply(1:10, function(...) runif(N)))
system.time(arrow::write_feather(x, "/dev/shm/data.feather"))
system.time(fwrite(x, "/dev/shm/data.csv", showProgress=FALSE))
rm(x)
## run python

unlink(paste0("/dev/shm/data.",c("csv","feather")))
N = 1e7L
x = setDT(lapply(1:10, function(...) paste0("id",sample.int(N))))
system.time(arrow::write_feather(x, "/dev/shm/data.feather"))
system.time(fwrite(x, "/dev/shm/data.csv", showProgress=FALSE))
rm(x)
## run python

unlink(paste0("/dev/shm/data.",c("csv","feather")))
import datatable as dt
import timeit
import gc
from pyarrow import feather

gc.collect()
t_start = timeit.default_timer()
x = dt.fread("/dev/shm/data.csv")
print(timeit.default_timer() - t_start, flush=True)
gc.collect()
t_start = timeit.default_timer()
y = x.to_pandas()
print(timeit.default_timer() - t_start, flush=True)
del x, y

gc.collect()
t_start = timeit.default_timer()
x = feather.read_feather("/dev/shm/data.feather", memory_map=False)
print(timeit.default_timer() - t_start, flush=True)
del x

我得到以下时间:

  • integer:
    • 写:羽毛 2.7s vs csv 5.7s
    • 阅读:羽毛 2.8s 与 csv 111s+3s
  • 双倍的:
    • 写:羽毛 5.7s vs csv 10.8s
    • 阅读:羽毛 5.1s 与 csv 180s+4.9s
  • 特点:
    • 写:羽毛 50.2s vs csv 2.8s
    • 阅读:羽毛 35s 与 csv 14s+16s

基于呈现的数据案例(1e8 行用于 int/double,1e7 行用于字符;10 列:int/double/character)我们可以得出以下结论:

  • 对于 csv,写入 int 和 double 比 feather 慢大约 2 倍
  • csv 的写入字符比羽毛快 20 倍左右
  • csv 的读取 int 和 double 比 feather 慢得多
  • 将 int 和 double 从 python 数据表转换为 pandas 相对便宜
  • csv 的读取字符比羽毛快 2 倍左右
  • 从 python 数据表到 pandas 的转换字符很昂贵

请注意,这些是非常基本的数据案例,请务必检查实际数据的时间。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM