从长到宽重塑数据集的有效方法

问题描述 投票:0回答:1

我有一个看起来像这样的医学数据集:

patient_id disease_id 
1111111111  DISEASE:1
1111111111  DISEASE:2
1111111111  DISEASE:3
1111111111  DISEASE:4
1111111111  DISEASE:5 
1111111111  DISEASE:6
1111111111  DISEASE:6
1111111112  DISEASE:1
1111111112  DISEASE:2
1111111112  DISEASE:4
1111111113  DISEASE:1
1111111113  DISEASE:5

我需要输入神经网络/随机森林模型。因此,唯一想到的自然数据表示形式就是:

    patient_id   DISEASE:1  DISEASE:2  DISEASE:3  DISEASE:4  DISEASE:5  DISEASE:6  ...
    11111111111     1           1           1           1           1        1     ...  
    11111111112     1           1           0           1           0        0     ...    
    11111111113     1           0           0           0           1        0     ...

但是我的数据集非常大(〜50GB,压缩后的1.5 GB),并且具有大量的disease_id,因此在R中以最有效的方式重塑该数据需要在压缩后的中有11.7 TB的空间RD格式(我知道这是因为我将数据集分为100个块,并且对单个数据集进行重塑会产生117 GB的沉重RD文件;将其中的100个合并将产生大于11.7TB的空间)。

现在,我有5个需要合并的大数据集,所以我感觉有些卡住。我需要提出一个更有效的数据表示形式,但不知道如何处理需要1-hot编码的分类变量。任何人都可以建议其他替代方法来处理此类数据。

r dataframe bigdata out-of-memory
1个回答
0
投票

您提出了一个有趣的问题。用R分析该数据量将是一次真正的改变。

所以,我只能给您一般建议。首先,我认为您需要分离RAM和磁盘存储。使用Rds不会帮助您改善整形的效率,但与csv相比,它将在磁盘上产生较小的数据。

关于重塑的效率

数据表

如果您要采用内存方式,除了使用data.table::dcast之外,我没有其他可能性。在这种情况下,请遵循@Ronak Shah的建议:

library(data.table)
setDT(df)
df[, n := 1]
dcast(unique(df), patient_id~ disease_id, value.var = "n", fill = 0)

其他解决方案

对于海量数据,我认为内存不是最合适的。您可能会看一下数据库方法(尤其是postgreSQL)或Spark

数据库您可以使用几个选项来使用postgreSQL中的R。其中之一是dbplyr:如果您知道tidyverse语法,就会发现熟悉的动词。与标准R数据框相比,数据透视表操作对数据库而言有些棘手,但您可能会发现some ways to do that。您可以找到比我更多的数据库专家,这将给您带来很多有趣的窍门。

spark Spark可以很好地进行重塑,如果您可以在伺服器中的执行者之间分散任务。如果您使用的是个人计算机(独立模式),则仍可以并行执行内核之间的任务,但是不要忘记更改会话的spark.memory.fraction参数,否则我认为您可能会遇到out of memory问题。我比pyspark更习惯sparkR,但我认为逻辑是相同的。

Spark 1.6起,您就可以透视数据(ex: pyspark doc)。这样可以实现widelong的转换。本着这种精神

df.withColumn("n", psf.lit(1)).pivot("patient_id").sum("n")

关于磁盘的大小

您使用Rds。您需要对某些格式进行更多压缩,例如fstparquet文件也非常压缩,这也许是存储大量数据的最佳选择之一。您可以使用Spark或使用arrow软件包阅读它们

© www.soinside.com 2019 - 2024. All rights reserved.