我试图从sparknlp中提取输出(使用预训练的管道“explain_document_dl”)。我花了很多时间寻找方法(udf、explode等),但始终无法找到可行的解决方案。假设我想从entities
列中获得result
和metadata
下的提取值。在该列中有一个包含多个字典的数组
当我使用df.withColumn("entity_name", explode("entities.result"))
时,只提取第一个字典中的值。在
“实体”列的内容是字典列表。在
尝试提供一个可复制的示例/重新创建数据帧(感谢@jonathan下面提供的建议):
# content of one cell as an example:
d = [{"annotatorType":"chunk","begin":2740,"end":2747,"result":"•Ability","metadata":{"entity":"ORG","sentence":"8","chunk":"22"},"embeddings":[],"sentence_embeddings":[]}, {"annotatorType":"chunk","begin":2740,"end":2747,"result":"Fedex","metadata":{"entity":"ORG","sentence":"8","chunk":"22"},"embeddings":[],"sentence_embeddings":[]}]
from pyspark.sql.types import StructType, StructField, StringType
from array import array
schema = StructType([StructField('annotatorType', StringType(), True),
StructField('begin', IntegerType(), True),
StructField('end', IntegerType(), True),
StructField('result', StringType(), True),
StructField('sentence', StringType(), True),
StructField('chunk', StringType(), True),
StructField('metadata', StructType((StructField('entity', StringType(), True),
StructField('sentence', StringType(), True),
StructField('chunk', StringType(), True)
)), True),
StructField('embeddings', StringType(), True),
StructField('sentence_embeddings', StringType(), True)
]
)
df = spark.createDataFrame(d, schema=schema)
df.show()
在这种情况下,只有一个字典列表,它可以工作:
^{pr2}$但我一直在讨论如何将其应用于列,该列包含具有多个字典数组的一些单元格(因此原始单元格有多行)。在
我尝试对entities
列应用相同的模式,必须先将该列转换为json。在
ent1 = ent1.withColumn("entities2", to_json("entities"))
它适用于数组为1个字典的单元格,但将null
提供给具有多个字典数组的单元格(第4行):
ent1.withColumn("entities2", from_json("entities2", schema)).select("entities2.*").show()
+-------------+-----+----+------+--------+-----+------------+----------+-------------------+
|annotatorType|begin| end|result|sentence|chunk| metadata|embeddings|sentence_embeddings|
+-------------+-----+----+------+--------+-----+------------+----------+-------------------+
| chunk| 166| 169| Lyft| null| null|[MISC, 0, 0]| []| []|
| chunk| 11| 14| Lyft| null| null|[MISC, 0, 0]| []| []|
| chunk| 52| 55| Lyft| null| null|[MISC, 1, 0]| []| []|
| null| null|null| null| null| null| null| null| null|
+-------------+-----+----+------+--------+-----+------------+----------+-------------------+
所需输出为
+-------------+-----+----+----------------+------------------------+----------+-------------------+
|annotatorType|begin| end| result | metadata |embeddings|sentence_embeddings|
+-------------+-----+----+----------------+------------------------+----------+-------------------+
| chunk| 166| 169|Lyft |[MISC] | []| []|
| chunk| 11| 14|Lyft |[MISC] | []| []|
| chunk| 52| 55|Lyft. |[MISC] | []| []|
| chunk| [..]|[..]|[Lyft,Lyft, |[MISC,MISC,MISC, | []| []|
| | | |FedEx Ground..] |ORG,LOC,ORG,ORG,ORG,ORG]| | |
+-------------+-----+----+----------------+------------------------+----------+-------------------+
我还尝试将每一行转换为json,但是我失去了原始行的踪迹,并得到了flatted-son:
new_df = sqlContext.read.json(ent2.rdd.map(lambda r: r.entities2))
new_df.show()
+-------------+-----+----------+----+------------+----------------+-------------------+
|annotatorType|begin|embeddings| end| metadata| result|sentence_embeddings|
+-------------+-----+----------+----+------------+----------------+-------------------+
| chunk| 166| []| 169|[0, MISC, 0]| Lyft| []|
| chunk| 11| []| 14|[0, MISC, 0]| Lyft| []|
| chunk| 52| []| 55|[0, MISC, 1]| Lyft| []|
| chunk| 0| []| 11| [0, ORG, 0]| FedEx Ground| []|
| chunk| 717| []| 720| [1, LOC, 4]| Dock| []|
| chunk| 811| []| 816| [2, ORG, 5]| Parcel| []|
| chunk| 1080| []|1095| [3, ORG, 6]|Parcel Assistant| []|
| chunk| 1102| []|1108| [4, ORG, 7]| • Daily| []|
| chunk| 1408| []|1417| [5, ORG, 8]| Assistants| []|
+-------------+-----+----------+----+------------+----------------+-------------------+
我尝试应用UDF来查看“实体”中的数组列表:
def flatten(my_dict):
d_result = defaultdict(list)
for sub in my_dict:
val = sub['result']
d_result["result"].append(val)
return d_result["result"]
ent = ent.withColumn('result', flatten(df.entities))
TypeError: Column is not iterable
我发现这篇文章Apache Spark Read JSON With Extra Columns与我的问题非常相似,但是在将entities
列转换为json之后,我仍然无法通过该帖子中提供的解决方案来解决它。在
感谢任何帮助!!理想的解决方案是python,但scala的例子也很有用!在
获取
null
的原因是,schema
变量并不完全表示作为数据传递的字典列表如果您喜欢定制的解决方案,可以尝试纯python/pandas方法
^{pr2}$编辑
在阅读了您尝试过的所有方法之后,我认为{}仍然可以在相当复杂的情况下使用。我没有你最初的变量,但我可以从中提取你的图像,尽管不再有课堂教师或教学值。希望它对所有有用的东西都有用。在
您总是可以创建一个具有所需结构和get模式的mock数据帧
对于具有嵌套数据类型的复杂情况,可以使用SparkContext并读取生成的JSON格式
输出:
您必须分别从每个数据帧中进行选择,因为它们的数据类型不同,但是内容已经准备好了(如果我从输出中理解了您的需求的话)
(͜͡ʖ͡͡)
相关问题 更多 >
编程相关推荐