Python 从堆叠的json文件复制数据帧-速度问题
我想导入一个json文件(尽管它看起来更像一个普通的txt文件),其中每一行都是一个小的(四个数据对)json文件。 每个json文件都应该是熊猫数据框架中的一行,有四列 例如:Python 从堆叠的json文件复制数据帧-速度问题,python,json,pandas,dataframe,Python,Json,Pandas,Dataframe,我想导入一个json文件(尽管它看起来更像一个普通的txt文件),其中每一行都是一个小的(四个数据对)json文件。 每个json文件都应该是熊猫数据框架中的一行,有四列 例如: #在“data.json”中 {“时间”:“2020-07-01:14:27:16.0000”,“id”:“m38dk117”,“位置”:“66277”,“当前有效”:“17.1”} {“时间”:“2020-07-01:14:27:16.0000”,“id”:“m38dk118”,“位置”:“3277”,“有效电流”:
#在“data.json”中
{“时间”:“2020-07-01:14:27:16.0000”,“id”:“m38dk117”,“位置”:“66277”,“当前有效”:“17.1”}
{“时间”:“2020-07-01:14:27:16.0000”,“id”:“m38dk118”,“位置”:“3277”,“有效电流”:“0.0”}
...
{“时间”:“2020-07-30:14:27:16.0000”,“id”:“m38dk006”,“位置”:“73117”,“当前有效”:“0.0”}
data.json大约30MB大,每天包含大约250000行
data.json大约有900MB大,每个月包含大约750万行
下面的代码片段可以完成这项工作,但速度太慢。
熊猫的其他选择也是受欢迎的,我并不局限于熊猫。但缺乏处理大量日志数据的经验
提议:
将熊猫作为pd导入
导入json
df=pd.DataFrame()
将open('data.json','r')作为堆叠的json文件:
行_idx=-1
对于堆叠的json_文件中的json_文件:
行_idx+=1
df=df.append(pd.DataFrame(json.loads(json\u文件),index=[row\u idx]))
这是否可能是因为pd.DataFrame.append没有适当地追加?应该可以
pd.read_json('data.json', lines=True)
输出:
如果这不起作用:
假设您的数据不是有效的json,而是每行都包含json对象的文本文件。您可以先创建dict列表,以避免附加到数据帧
with open('data.json', 'r') as f:
dictlist = [json.loads(x) for x in f]
pd.DataFrame(dictlist)
输出:
微观基准 比较迭代追加,创建字典列表和 结果 用于基准测试的代码
import pandas as pd
import json
import io
def makedata(n):
t = '''{"time": "2020-07-01:14:27:16.0000", "id": "m38dk117", "position": "66277", "active_current": "17.1"}
{"time": "2020-07-01:14:27:16.0000", "id": "m38dk118", "position": "3277", "active_current": "0.0"}
{"time": "2020-07-30:14:27:16.0000", "id": "m38dk006", "position": "73117", "active_current": "0.0"}
''' * n
return t
def pdjson(file):
return pd.read_json(io.StringIO(file), lines=True)
def dictlist(file):
with io.StringIO(file) as f:
l = [json.loads(x) for x in f]
return pd.DataFrame(l)
def appenddf(file):
df = pd.DataFrame()
with io.StringIO(file) as stacked_json_file:
row_idx = -1
for json_file in stacked_json_file:
row_idx += 1
df = df.append(pd.DataFrame(json.loads(json_file), index = [row_idx]))
return df
import perfplot
perfplot.show(
setup = makedata,
kernels = [appenddf, dictlist, pdjson],
n_range= [2**k for k in range(5,16)],
equality_check=None,
xlabel='len(df)'
);
这应该行得通
pd.read_json('data.json', lines=True)
输出:
如果这不起作用:
假设您的数据不是有效的json,而是每行都包含json对象的文本文件。您可以先创建dict列表,以避免附加到数据帧
with open('data.json', 'r') as f:
dictlist = [json.loads(x) for x in f]
pd.DataFrame(dictlist)
输出:
微观基准 比较迭代追加,创建字典列表和 结果 用于基准测试的代码
import pandas as pd
import json
import io
def makedata(n):
t = '''{"time": "2020-07-01:14:27:16.0000", "id": "m38dk117", "position": "66277", "active_current": "17.1"}
{"time": "2020-07-01:14:27:16.0000", "id": "m38dk118", "position": "3277", "active_current": "0.0"}
{"time": "2020-07-30:14:27:16.0000", "id": "m38dk006", "position": "73117", "active_current": "0.0"}
''' * n
return t
def pdjson(file):
return pd.read_json(io.StringIO(file), lines=True)
def dictlist(file):
with io.StringIO(file) as f:
l = [json.loads(x) for x in f]
return pd.DataFrame(l)
def appenddf(file):
df = pd.DataFrame()
with io.StringIO(file) as stacked_json_file:
row_idx = -1
for json_file in stacked_json_file:
row_idx += 1
df = df.append(pd.DataFrame(json.loads(json_file), index = [row_idx]))
return df
import perfplot
perfplot.show(
setup = makedata,
kernels = [appenddf, dictlist, pdjson],
n_range= [2**k for k in range(5,16)],
equality_check=None,
xlabel='len(df)'
);
试着通过df=pd.read_json('data.json')将json直接读取到pandas,注意:您必须使用的数据格式效率非常低。(压缩的)csv文件将节省大量导入空间和时间。我知道它通常不在我们的手中,但是我会考虑请求数据源来改变格式。尝试在一个旁注下直接用DF= Pd。Read JSON('DATA,JSON)读取JSON:您必须使用的数据格式是非常低效的。(压缩的)csv文件将节省大量导入空间和时间。我知道它经常不在我们手中,但是我会考虑请求数据源来改变格式。谢谢。工作完美。旁注:在dictlist方法中:用()替换[]来创建生成器是更有效还是可以忽略?如果是这样的话,我们该如何检查呢?我将列表和生成器与测试数据的小文件(~200MB)进行了比较:运行时的差异可以忽略不计。因此,对于大文件,如果内存使用受到关注,那么使用生成器似乎是一个不错的选择。谢谢。工作完美。旁注:在dictlist方法中:用()替换[]来创建生成器是更有效还是可以忽略?如果是这样的话,我们该如何检查呢?我将列表和生成器与测试数据的小文件(~200MB)进行了比较:运行时的差异可以忽略不计。因此,对于大文件,如果内存使用受到关注,那么使用生成器似乎是一个不错的选择。