Python 如何使用pySpark加快多个json的处理速度?
我在Databricks中有一个json文件列表,我试图读取每个json,提取所需的值,然后将其附加到一个空的数据框中。每个json文件对应于最终数据帧上的一行。初始json文件列表长度为50k。到目前为止,我构建的是下面的函数,它可以完美地完成这项工作,但它花费了太多的时间,使我将json文件列表子集到5k容器中,并分别运行每个容器。每次需要30分钟。我仅限于在Databricks中使用3节点群集 你有没有可能提高我的工作效率?提前谢谢。Python 如何使用pySpark加快多个json的处理速度?,python,python-3.x,pyspark,apache-spark-sql,databricks,Python,Python 3.x,Pyspark,Apache Spark Sql,Databricks,我在Databricks中有一个json文件列表,我试图读取每个json,提取所需的值,然后将其附加到一个空的数据框中。每个json文件对应于最终数据帧上的一行。初始json文件列表长度为50k。到目前为止,我构建的是下面的函数,它可以完美地完成这项工作,但它花费了太多的时间,使我将json文件列表子集到5k容器中,并分别运行每个容器。每次需要30分钟。我仅限于在Databricks中使用3节点群集 你有没有可能提高我的工作效率?提前谢谢。 ###创建一个包含所有json文件的大数据帧###
###创建一个包含所有json文件的大数据帧###
def jsons_至_pdf(所有路径):
#创建空数据帧(仅使用列名定义)
pdf=创建首字母pdf(样本文件)
#将每行追加到上述数据框中
对于所有_路径中的路径:
#创建spark数据帧
sdf=sqlContext.read.json(路径)
#创建两个提取的值列表
init_values=sdf.select(“id”、“logTimestamp”、“otherTimestamp”).rdd.flatMap(lambda x:x).collect()
id_values=sdf.select(sdf[“数据点”][“值”]).rdd.flatMap(lambda x:x).collect()[0]
#将连接的列表作为一行附加到初始数据帧中
loc[len(pdf)]=初始值+id值
返回pdf
一个json文件如下所示:
我想要实现的是将数据点['id']作为新列,将数据点['value']作为它们的值,从而最终得到这样的结果:根据您的示例,您想要执行的是一个透视,然后将数据转换为一个数据帧 这些步骤是:
- 将所有JSON收集到一个大数据框中
- 以数据为中心
- 将它们转换为数据帧
from functools import reduce
def jsons_to_pdf(all_paths):
# Create a big dataframe from all the jsons
sdf = reduce(
lambda a,b : a.union(b),
[
sqlContext.read.json(path)
for path
in all_paths
]
)
# select and pivot your data
pivot_df = sdf.select(
"imoNo",
"logTimestamp",
"payloadTimestamp",
F.explode("datapoints").alias("datapoint")
).groupBy(
"imoNo",
"logTimestamp",
"payloadTimestamp",
).pivot(
"datapoint.id"
).sum("datapoint.value")
# convert to a pandas dataframe
pdf = pivot_df.toPandas()
return pdf
根据您的评论,您可以将文件列表所有路径
替换为通用路径,并更改创建sdf
的方式:
all_paths = 'abc/*/*/*' # 3x*, one for year, one for month, one for day
def jsons_to_pdf(all_paths):
# Create a big dataframe from all the jsons
sdf = sqlContext.read.json(path)
这肯定会提高性能。感谢您的快速回答!当我用你的函数替换我的函数时,我得到
ValueError:无法设置列不匹配的行
,这是因为collect函数返回一个包含所有行信息的巨大列表,该列表不能添加到空数据框中。我可以对列表应用for循环,并将每组值(表示一行)以迭代方式添加到空数据帧中。但这可能会再次减缓这一进程。有没有想过如何替换最后3行代码,使其达到最初的目的?再次感谢!我真的不明白你为什么要逐行添加它。只需创建一列并将其添加到数据帧中。您不必事先创建列。此外,您有spark dataframesto_pandas
方法,可用于直接创建pandas dataframe。@oikonang我完全根据您提供的更改代码。但也许还有一些调整要做。嗨,史蒂文!您的代码按预期工作!但是执行处理仍然需要很多时间。让您了解一下,我的代码在1.1分钟内运行100个json文件,您的代码在1.07分钟内运行。它比我的要好,但如果你认为我有35k json文件,那么完成这项任务需要6.4个小时。有没有办法把它取下来?谢谢你的时间。不,它不是线性的。。。我的将花费越来越少的时间与您的相比请添加一些样本数据和预期输出。。。仅仅拥有代码很难理解您想要实现什么。可能是因为误用了spark。我编辑了我的问题。每个三元组都存在每个“id”(“imoNo”,timestamp,timestamp)?