我正在考虑编写一个函数来规范化一些数据。一个简单的方法是
def normalize(l, aggregate=sum, norm_by=operator.truediv):
aggregated=aggregate(l)
for i in range(len(l)):
l[i]=norm_by(l[i], aggregated)
l=[1,2,3,4]
normalize(l)
l -> [0.1, 0.2, 0.3, 0.4]
但是对于嵌套列表和dicts,我想在内部索引上进行规范化,这不起作用。我的意思是我想得到
l=[[1,100],[2,100],[3,100],[4,100]]
normalize(l, ?? )
l -> [[0.1,100],[0.2,100],[0.3,100],[0.4,100]]
我是如何实现这种规范化函数的?
编写
可能会很酷normalize(l[...][0])
是否有可能使这项工作?还是其他任何想法?
此外,不仅列表而且dict也可以嵌套。嗯...
编辑: 我刚刚发现numpy提供了这样的语法(但是对于列表)。任何人都知道我将如何实现省略号技巧?
答案 0 :(得分:4)
我认为不需要对normalize()
函数进行任何更改。要处理嵌套列表,您只需提供正确的aggregate()
和norm_by()
函数来处理案例。
l = [[1, 100], [2, 100], [3, 100], [4, 100]]
def aggregator(l):
return sum(item[0] for item in l)
def normalizer(item , aggregated):
# mutating the inner list
item[0] = operator.truediv(item[0], aggregated)
return item
normalize(l, aggregate = aggregator, norm_by = normalizer)
# l -> [[0.1, 100], [0.2, 100], [0.3, 100], [0.4, 100]]
答案 1 :(得分:0)
使用此:
zip(normalize(zip(*l)[0]), zip(*l)[1])
有一个(通常不重要)副作用:内部列表转换为元组。但是,可以使用[list(el) for el in zip(normalize(zip(*l)[0]), zip(*l)[1])]
更正此问题。
如果你有一个字典,我想它看起来像{'a': 1, 'b': 2}
,这些值需要规范化。您可以使用l.items()
:
dict(zip(normalize(zip(*l.items())[0]), zip(*l.items())[1]))
修改强>
你可以这样做:
def normalize(l, aggregate=sum, norm_by=operator.truediv, key=None):
aggregated=aggregate(l)
for i in range(len(l)):
if key is not None:
l[i][key] = norm_by(l[i][key], aggregated)
else:
l[i]=norm_by(l[i], aggregated)
用
调用该函数normalize(l, key=0)
答案 2 :(得分:0)
我建议创建新对象而不是就地修改。假设iterable中的每个元素可能不同(如果没有,您可以通过之前选择合并函数使其更有效):
def normalize(input, index=None, aggregate=sum, norm_by=operator.truediv):
aggregated = aggregate(input)
for item in input:
if isinstance(item, list):
yield item[:index] + [norm_by(item[index], aggregated)] + item[index+1:]
elsif isinstance(item, dict):
yield dict(d, **{index: norm_by(item[index], aggregated)})
else:
yield norm_by(item, aggregated)
待用:
normalize([1, 2, 3])
normalize([(1, 2), (3, 4)], 0)
normalize([{"a": 1, "b": 2}, {"a": 3, "b": 4}], "a")