在列表列表中反转浮点数

时间:2018-03-15 10:16:57

标签: python numpy nested-lists

我有一个Markov转换表的输出,这是一个包含59个浮点数的59个列表的列表。我想反转每个非0浮点数,然后对输出进行标准化,以便我再次得到一个概率列表,其中加起来为1.

我已经阅读了关于列表理解的教科书,这似乎是相关的,但我不能理解如何实现它。

列表列表为m

for i in range(59):
    [1/item for item in m[i] if item > 0.]
    i += 1

这会运行,但它不会改变m。我在这段代码中使用item是错误的吗?我应该使用其他参考吗?

4 个答案:

答案 0 :(得分:8)

[1/item for item in m[i] if item > 0.]创建一个新列表。然后你对该列表什么都不做。 Graipher告诉您的是,您需要引用新创建的列表:
m[i] = <your list comprehension>将分配回列表列的行i

另外,考虑numpy用于元素操作。演示:

>>> import numpy as np
>>> m = np.array([[1,2], [3, 0]])
>>> m = 1.0/m
>>> m
array([[ 1.        ,  0.5       ],
       [ 0.33333333,         inf]])
>>> m[m == np.inf] = 0
>>> m
array([[ 1.        ,  0.5       ],
       [ 0.33333333,  0.        ]])

答案 1 :(得分:5)

您需要在循环中将其分配回m[i]

for i in range(len(m)):
    m[i] = [1./item if item != 0. else item for item in m[i]]

并且不需要i+=1,因为for循环会为您执行此操作。

为了避免子列表比原始子列表短,您需要将if从列表推导的末尾(基本上过滤哪些项目处理)移到前面(因此值本身是{{ 3}}评估为1/itemitem,具体取决于item的值。

此时您应该观看演示文稿enter image description here并将其重写为例如:

for i, x in enumerate(m):
    m[i] = [1./item if item != 0. else item for item in x]

答案 2 :(得分:5)

[1/item for item in m[i] if item > 0.]单独在一条线上创建一个一次性对象。不太有用。

我的建议:使用双重理解重建您的列表列表:

m = [[1./item for item in sm if item > 0.] for sm in m]

这个解决方案是关于浮点除法的Python 2/3兼容列表包含的内容(整数或浮点数)

编辑:引用问题:“我想反转每个非0浮点数”,公式不正确,因为它不包含零。所以更准确的版本不是过滤,而是用三元测试表达式,因此它保持零。

m = [[1./item if item else 0. for item in sm] for sm in m]

if item是针对0)测试项目的快捷方式

答案 3 :(得分:2)

如果可能,我建议您使用专门为此目的设计的工具。

在下面的矢量化解决方案中,通过numpy进行就地,并使用sklearn.preprocessing.normalize进行规范化。

import numpy as np
from sklearn.preprocessing import normalize

arr = np.array([1, 2, 0, 1, 1, 0, 4, 0], dtype=float)

def inv(A):
    m = (A != 0)
    A[m] = 1/A[m]
    return A

res = normalize(inv(arr))

# [[ 0.54944226  0.27472113  0.          0.54944226  0.54944226  0.
#    0.13736056  0.        ]]
相关问题