【问题标题】:Normalize a dictionary of dictionaries in Python规范化 Python 中的字典字典
【发布时间】:2020-12-07 22:03:21
【问题描述】:

我正在学习编码,但我仍然不太擅长。我的问题是我有一个矿物的 Python 字典,每种矿物(键)都有另一个字典作为值,我可以在其中读取属性。 例如

"Quartz": {
"Zeff-2.94": 11.560477823722744,
"Rhoe": 7.968143490069414e+23
},
"Siderite": {
"Zeff-2.94": 20.242908072785397,
"Rhoe": 1.1265233868351479e+24
},
.....etc }

然后,我必须将“大矿物词典”中的所有“Zeff”值和所有“Rhoe”值标准化为 0 到 1。我想写一个循环,但它不起作用:

import CommonMinerals_database 
import math 
import numpy as np
from sklearn.preprocessing import normalize

norm_mineral_database = {}
for k in CommonMinerals_database.COMMON_MINERALS_DATABASE.keys(): 
    norm_mineral = COMMON_MINERALS_DATABASE[k] 
    Zeff_norm = normalize(norm_mineral["Zeff-2.94"])  
    rhoe_norm = normalize(norm_mineral["Rhoe"])
print(norm_mineral_database)

我的目标是获取另一个矿物字典(即使它看起来不像“普通”python 字典),我可以在其中读取规范化的属性。 拜托,你能帮帮我吗? 提前谢谢!

【问题讨论】:

  • 如果有什么错误,在哪一行?
  • ValueError: 预期的二维数组,得到的是标量数组:array=13.26645845673176。如果您的数据具有单个特征,则使用 array.reshape(-1, 1) 重塑您的数据,如果它包含单个样本,则使用 array.reshape(1, -1)。

标签: python dictionary for-loop database-normalization normalize


【解决方案1】:

使用列表理解很容易,作为简化,我假设只有 2 种矿物,但它应该适用于更大的 dict。不确定你想使用什么样的规范化,所以如果需要修改代码

import numpy as np

d = {"Quartz": {
"Zeff-2.94": 11.560477823722744,
"Rhoe": 7.968143490069414e+23
},
"Siderite": {
"Zeff-2.94": 20.242908072785397,
"Rhoe": 1.1265233868351479e+24
}}

a =  np.sum([d[key]["Zeff-2.94"] for key in d.keys()])
b = np.sum([d[key]["Rhoe"] for key in d.keys()])

new_dict = {key:{"Zeff_norm":d[key]["Zeff-2.94"]/a,"Rhoe_norm":d[key]["Rhoe"]/b} for key in d.keys()}

编辑: 上面的情况是使用元素的总和作为范数。

如果你想要一个最小-最大归一化check this 看看如何手动完成。

d = {"Quartz": {
"Zeff-2.94": 11.560477823722744,
"Rhoe": 7.968143490069414e+23
},
"Siderite": {
"Zeff-2.94": 20.242908072785397,
"Rhoe": 1.1265233868351479e+24
},
"Mineral3:":{
"Zeff-2.94":15,
"Rhoe":1e+24}}


min_Zeff = np.min([d[key]["Zeff-2.94"] for key in d.keys()])
max_Zeff = np.max([d[key]["Zeff-2.94"] for key in d.keys()])
range_Zeff = max_Zeff - min_Zeff

min_Rhoe = np.min([d[key]["Rhoe"] for key in d.keys()])
max_Rhoe = np.max([d[key]["Rhoe"] for key in d.keys()])
range_Rhoe = max_Rhoe - min_Rhoe

new_dict = {key:{"Zeff_norm":(d[key]["Zeff-2.94"] - min_Zeff)/range_Zeff,"Rhoe_norm":(d[key]["Rhoe"]-min_Rhoe)/range_Rhoe} for key in d.keys()}

print(new_dict)

或者检查MinMaxScaler

from sklearn.preprocessing import MinMaxScaler
import numpy as np

d = {"Quartz": {
"Zeff-2.94": 11.560477823722744,
"Rhoe": 7.968143490069414e+23
},
"Siderite": {
"Zeff-2.94": 20.242908072785397,
"Rhoe": 1.1265233868351479e+24
},
"Mineral3:":{
"Zeff-2.94":15,
"Rhoe":1e+24}}

scaler = MinMaxScaler()

Zeff = [d[key]["Zeff-2.94"] for key in d]
Rhoe = [d[key]["Rhoe"] for key in d]

Zeff_norm = scaler.fit_transform(np.array(Zeff).reshape(-1,1)).T[0]
Rhoe_norm = scaler.fit_transform(np.array(Rhoe).reshape(-1,1)).T[0]

new_dict = {key:{"Zeff_norm":Zeff_norm[i],"Rhoe_norm":Rhoe_norm[i]} for i,key in enumerate(d.keys())}
print(new_dict)

【讨论】:

  • 嗨洛伦佐!非常感谢!只是一个问题......你告诉我你不确定我需要完成的规范化。实际上,我想在我的字典中取 Zeff 和 Rhoe 的最大值和最小值,然后标准化,获得 0 和 1 之间的值(例如,具有较大 Zeff 的矿物将是该属性的 1)。我尝试运行您建议我的代码,看起来很棒,但我既没有 0 也没有 1。这不正常,不是吗?非常感谢您的帮助!
  • 我编辑了答案。看看这是否有效。可能第一个答案不起作用,因为您的数据具有负值,对吗?
  • 嗨洛伦佐!实际上不是,数据值总是正的;我尝试了您的第一个答案,它似乎很完美!非常感谢您的帮助:-)
猜你喜欢
  • 1970-01-01
  • 2020-12-31
  • 2013-05-30
  • 1970-01-01
  • 2021-07-11
  • 2021-03-23
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多