如何对 .json 文件进行下采样

Posted

技术标签:

【中文标题】如何对 .json 文件进行下采样【英文标题】:How to downsample .json file 【发布时间】:2020-04-12 22:57:33 【问题描述】:

如果这是一个非常初学者的问题,我深表歉意。但是我有一个来自 reddit (https://files.pushshift.io/reddit/submissions/) 的多元数据集,但是文件太大了。是否可以将其中一个文件降低到 20% 或更少,并将其保存为新文件(json 或 csv)或直接将其作为 pandas 数据帧读取?任何帮助将不胜感激!

这是我迄今为止的尝试

def load_json_df(filename, num_bytes = -1):
    '''Load the first `num_bytes` of the filename as a json blob, convert each line into a row in a Pandas data frame.'''
    fs = open(filename, encoding='utf-8')
    df = pd.DataFrame([json.loads(x) for x in fs.readlines(num_bytes)])
    fs.close()
    return df

january_df = load_json_df('RS_2019-01.json')

january_df.sample(frac=0.2)

但是,这在尝试打开它时给了我一个内存错误。有没有办法在不打开整个文件的情况下对其进行下采样?

【问题讨论】:

数据似乎是压缩的 JSON 行。您可以使用系统工具(例如bzip2)对其进行解压缩,然后将其通过管道传输到读取一行、做出决定并在肯定时将该行写入文件的 python 进程中。将所有文件加载到内存中会给您带来麻烦。 请接受可以解决您问题的答案。谢谢 【参考方案1】:

问题是,无法准确确定这 20% 的数据是什么。为此,您必须首先阅读文件的整个长度,然后才能了解 20% 的样子。

一次将大文件全部读入内存通常会引发此错误。您可以通过使用以下代码逐行读取文件来处理此问题:

data = []
counter = 0
with open('file') as f:
    for line in f:
        data.append(json.loads(line))
        counter +=1

你应该能够做到这一点

df = pd.DataFrame([x for x in data]) #you can set a range here with counter/5 if you want to get 20%

【讨论】:

【参考方案2】:

我下载了第一个文件,即https://files.pushshift.io/reddit/submissions/RS_2011-01.bz2 解压后查看内容。碰巧,它不是一个正确的 JSON,而是 JSON 行——一系列 JSON 对象,每行一个(参见http://jsonlines.org/)。这意味着您可以使用任何您想要的工具(例如,文本编辑器)剪切任意多的行。或者您可以在 Python 脚本中按顺序处理文件,考虑到每五行,如下所示:

with open('RS_2019-01.json', 'r') as infile:
    for i, line in enumerate(infile):
        if i % 5 == 0: 
             j = json.loads(line)
             # process the data here

【讨论】:

以上是关于如何对 .json 文件进行下采样的主要内容,如果未能解决你的问题,请参考以下文章

如何对信号保持尖峰进行下采样?

如何通过 2x2 平均内核对 pandas 数据帧进行下采样

使用 afconvert 对 wav (LEI16) 文件进行下采样

如何根据条件在 Python 中对数据帧进行下采样

如何使不同长度的不同数据帧长度相等(下采样和上采样)

如何在不等待 1 秒的情况下对进程的 CPU 使用情况进行采样