将 17GB JSON 文件转换为 numpy 数组
Posted
技术标签:
【中文标题】将 17GB JSON 文件转换为 numpy 数组【英文标题】:Convert 17GB JSON file to a numpy array 【发布时间】:2018-06-03 19:17:45 【问题描述】:我有一个 17 GB 的大 JSON 文件放在 hdfs 中。我需要读取该文件并将其转换为数字数组,然后将其传递给 K-Means 聚类算法。我尝试了很多方法,但系统速度变慢并出现内存错误或内核死机。
我试过的代码是
from hdfs3 import HDFileSystem
import pandas as pd
import numpy as nm
import json
hdfs = HDFileSystem(host='hostname', port=8020)
with hdfs.open('/user/iot_all_valid.json/') as f:
for line in f:
data = json.loads(line)
df = pd.DataFrame(data)
dataset= nm.array(df)
我尝试使用 ijson,但仍然不确定哪种方法可以更快地完成此操作。
【问题讨论】:
我的意思是。如何。如何。人们如何获得 17GB 的 JSON 文件?当人们停下来并说“嘿,这是表格数据,有几百万行,我想知道表格数据格式是否会比这种一般的无结构 JSON 混乱更好”时,难道没有什么意义吗? :(数据来自IOT传感器,存储在Hadoop中。 是的,但没有任何物联网传感器会单独向您发送 17GB JSON 文件。您在某处聚合了该数据并决定将其转储到单个 JSON 文件中。这是一个错误。如果是在 Hadoop 中,我敢肯定有比 JSON 更好的导出格式。 其实Hadoop是一个数据存储和分析框架。您可能应该直接使用您的 hadoop 实例来获取您想要的数据,而不是使用数据库的转储。 (这感觉很明显,但我认为它可能仍然值得为未来的读者写)。 【参考方案1】:我会远离 numpy 和 Pandas,因为在这两种情况下都会遇到内存问题。我宁愿坚持使用SFrame 或the Blaze ecosystem,它们是专门为处理这种“大数据”案例而设计的。很棒的工具!
【讨论】:
在您看来,您如何看待将部分数据加载到 panda 数据帧中,例如,假设您在一个文件中有 1 亿行并且您想使用 pandas,您有一个分区键,例如100k 行与每个键相关,在这种情况下,您不认为您可以使用一个键读取 100k 行,移动到下一个吗?【参考方案2】:因为每列的数据类型都不同,所以 pandas 数据框将是一个更合适的数据结构来保存它。您仍然可以使用 numpy 函数来操作数据。
import pandas as pd
data = pd.read_json('/user/iot_all_valid.json', dtype=<express converters for the different types here>)
为了避免崩溃问题,请尝试在数据集的小样本上运行 k-means。确保按预期工作。然后您可以增加数据大小,直到您对整个数据集感到满意为止。
【讨论】:
好的..另外我不希望 Json 中的所有元素只有 4 个元素用于算法。有没有办法只捡那些?选择 "macAddress","value"."speed", "value"."trackId", "value"."trackPos", "value"."battery" 其中 "deviceType"='AnkiCar' 和 "param"='状态' @MKN 您问题中的示例图像不包含这些字段。如果您包含一些示例数据会很有帮助。【参考方案3】:为了处理一个可能比可用内存大的 numpy 数组,我会使用memory mapped numpy array。在我的机器上,ujson 比内置 json 快 3.8 倍。假设rows是json的行数:
from hdfs3 import HDFileSystem
import numpy as nm
import ujson as json
rows=int(1e8)
columns=4
# 'w+' will overwrite any existing output.npy
out = np.memmap('output.npy', dtype='float32', mode='w+', shape=(rows,columns))
with hdfs.open('/user/iot_all_valid.json/') as f:
for row, line in enumerate(f):
data = json.loads(line)
# convert data to numerical array
out[row] = data
out.flush()
# memmap closes on delete.
del out
【讨论】:
以上是关于将 17GB JSON 文件转换为 numpy 数组的主要内容,如果未能解决你的问题,请参考以下文章
将 numpy 数组列表转换为 json 以从烧瓶 api 返回
将稀疏 scipy 矩阵加载到现有的 numpy 密集矩阵中