在 Python 中解析嵌套的 Json 以删除列中的特殊字符
Posted
技术标签:
【中文标题】在 Python 中解析嵌套的 Json 以删除列中的特殊字符【英文标题】:Parse Nested Json in Python to Remove Special Characters in Columns 【发布时间】:2019-04-13 00:04:21 【问题描述】:这是我的 Json 文件
"highest_table":
"items": [
"key": "Human 1",
"columns":
"Na$me": "Tom",
"Description(ms/2)": "Table Number One on the Top",
"A&ge": "24",
"Ge_nder": "M"
,
"key": "Human 2",
"columns":
"Na$me": "John",
"Description(ms/2)": "Table Number One on the Top",
"A&ge": "23",
"Ge_nder": "M"
]
我们的目标是删除列名中的所有特殊字符(或者如果更简单的话,删除 .json 文件中的任何特殊字符),并返回一个 .json 文件。 我最初的想法是将其转换为 pandas,删除列标题中的特殊字符并将其转换回 .json 文件。
这是我迄今为止尝试过的。它们都只打印一行。
import json
from pandas.io.json import json_normalize
data_file = r"C:\characters.json"
with open(data_file) as data_file:
data = json.load(data_file)
df = json_normalize(data)
--
data_file = r"C:\characters.json"
df = pd.read_json(data_file)
如何提取列、删除特殊字符并将它们放回 .json 文件中?
【问题讨论】:
创建 JSON 的原因是什么?这是在你的控制范围内,还是你只需要忍受这种格式? @roganjosh 这是我从中检索此 json 的网站服务器 糟糕的 API :( 你可以用json
模块做到这一点,但你必须重建整个响应,除非我错过了一个技巧
所以不幸的是我不得不忍受这种格式@roganjosh
正在处理它:)
【参考方案1】:
有点问答 - 您必须为 fixkey
提供完整的实现,但这应该可以解决您的问题。
import json
def fixkey(key):
# toy implementation
#print("fixing ".format(key))
return key.replace("&", "").replace("$", "")
def normalize(data):
#print("normalizing ".format(data))
if isinstance(data, dict):
data = fixkey(key): normalize(value) for key, value in data.items()
elif isinstance(data, list):
data = [normalize(item) for item in data]
return data
jsdata = """
"highest_table":
"items": [
"key": "Human 1",
"columns":
"Na$me": "Tom",
"Description(ms/2)": "Table Number One on the Top",
"A&ge": "24",
"Ge_nder": "M"
,
"key": "Human 2",
"columns":
"Na$me": "John",
"Description(ms/2)": "Table Number One on the Top",
"A&ge": "23",
"Ge_nder": "M"
]
"""
data = json.loads(jsdata)
data = normalize(data)
result = json.dumps(data, indent=2)
print(result)
【讨论】:
很好,我没有发现那条攻击线。 递归是嵌套数据结构的方法;-) @brunodesthuilliers ,使用 sub 而不是 replace 怎么样。如,string = re.sub("!@#$%^&*()[];:,./<>?\|~-=_+"]', '', key)
@JimmyStack 正如我所提到的,fixkey
的实现取决于您 - re.sub()
确实是可能的解决方案之一,这取决于您的需求以及您发现最合适的 wrt/可维护性和最终表现(如果这是您的用例的一个问题)。请注意,Python 字符串有一个 translate()
方法,在这里可能更有效。
@brunodesthuilliers 关于您的函数中的第二个elif
的问题。特别是[normalize(item)..
。你能解释一下那部分是做什么的吗?是否再次规范化调用该函数?【参考方案2】:
坦率地说,这丑,但我还没有找到更通用的方法。这对于您的特定 JSON 非常具体(这个问题确实需要在 API 中解决)。
import json
response = """
"highest_table":
"items": [
"key": "Human 1",
"columns":
"Na$me": "Tom",
"Description(ms/2)": "Table Number One on the Top",
"A&ge": "24",
"Ge_nder": "M"
,
"key": "Human 2",
"columns":
"Na$me": "John",
"Description(ms/2)": "Table Number One on the Top",
"A&ge": "23",
"Ge_nder": "M"
]
"""
def fix_json(resp):
output = 'highest_table': 'items': []
for item in resp['highest_table']['items']:
inner_dict = item['columns']
fixed_values = 'Name': inner_dict['Na$me'],
'Description(ms/2)': inner_dict['Description(ms/2)'],
'Age': inner_dict['A&ge'],
'Gender': inner_dict['Ge_nder']
new_inner = 'key': item['key'], 'columns': fixed_values
output['highest_table']['items'].append(new_inner)
return output
response = json.loads(response)
fixed = fix_json(response)
【讨论】:
谢谢你的回答,2个问题,1)你为什么说真正的问题在.api中? api有什么问题?第二个问题,不是物理删除这三列的特殊字符,我们可以让它成为列的循环并删除特殊字符吗? "你为什么说真正的问题出在 .api" => 因为它返回丑陋的(即使在技术上是有效的)json。 @JimmyStack 1) 因为当您使用的 API 生成响应时,损害已经造成。数据提供者解决这个问题要简单得多(这些字符在键中没有逻辑位置)。 2) 我不相信我能做出一个更通用的解决方案来修复任意嵌套的结构。 "我们可以让它循环到列并删除特殊字符吗?" => 参考我自己的答案以获得更通用的解决方案。以上是关于在 Python 中解析嵌套的 Json 以删除列中的特殊字符的主要内容,如果未能解决你的问题,请参考以下文章
使用包含嵌套 JSON 字符串的一列解析 Pandas DataFrame 中的列