如何对 .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 数据帧进行下采样