Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/json/14.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 从PySpark GroupBy中的两列创建JSON字符串_Python_Json_Pyspark - Fatal编程技术网

Python 从PySpark GroupBy中的两列创建JSON字符串

Python 从PySpark GroupBy中的两列创建JSON字符串,python,json,pyspark,Python,Json,Pyspark,我有一个数据框,看起来是这样的: >>l=[('a','foo',1),('b','bar',1),('a','biz',6),('c','bar',3),('c','biz',2)] >>>df=spark.createDataFrame(l,('uid','code','level')) >>>df.show() +---+----+-----+ |uid |代码|级别| +---+----+-----+ |a|foo|1| |b |巴| 1| |a|biz|6| |c | bar | 3|

我有一个数据框,看起来是这样的:

>>l=[('a','foo',1),('b','bar',1),('a','biz',6),('c','bar',3),('c','biz',2)]
>>>df=spark.createDataFrame(l,('uid','code','level'))
>>>df.show()
+---+----+-----+
|uid |代码|级别|
+---+----+-----+
|a|foo|1|
|b |巴| 1|
|a|biz|6|
|c | bar | 3|
|商业2|
+---+----+-----+
我试图做的是将
code
level
值分组到
dict
列表中,并将该列表作为JSON字符串转储,以便将数据帧保存到磁盘。结果如下:

df.show() +---+--------------------------+ |uid| json| +---+--------------------------+ |a |'[{“foo”:1},{“biz”:6}'| |b |'[{“bar”:1}]'| |c |'[{“酒吧”:3},{“商业”:2}]| +---+--------------------------+
我对使用PySpark还是一个新手,我很难弄清楚如何得到这个结果。我几乎肯定需要一个
groupBy
,我尝试通过创建一个名为“json”的新
StringType
列,然后使用
pandas\u udf
装饰器来实现这一点,但我发现关于不可处理类型的错误,因为我访问数据的方式是访问整个列,不仅仅是争吵

>>> df = df.withColumn('json', F.list(''))
>>> schema = df.schema
>>> @pandas_udf(schema, F.PandasUDFType.GROUPED_MAP)
..: def to_json(pdf):
..:     return pdf.assign(serial=json.dumps({pdf.code:pdf.level}))

我曾考虑在两列之间使用字符串连接,并使用
collect\u set
,但这感觉也不对,因为它可能会将无法加载JSON的内容写入磁盘,而这仅仅是因为它具有字符串表示。非常感谢您的帮助。

在这种情况下,不需要
pandas\u udf
到_json
收集_列表
创建_地图
应该是您所需要的全部:

import pyspark.sql.functions as f

df.groupby('uid').agg(
  f.to_json(
    f.collect_list(
      f.create_map('code', 'level')
    )
  ).alias('json')
).show(3, False)
+---+---------------------+
|uid|json                 |
+---+---------------------+
|c  |[{"bar":3},{"biz":2}]|
|b  |[{"bar":1}]          |
|a  |[{"foo":1},{"biz":6}]|
+---+---------------------+

如果在这里只使用一列,即level,我想为json提供自己的结构,会怎么样?例如,
[{first:3,status:null},{second:2,status:“pending”}]
并保持uid列不变。