我想用最后一个已知值替换缺失值(None)。这是我的代码。但它不起作用。有关更好算法的任何建议吗?
t = [[1, 3, None, 5, None], [2, None, None, 3, 1], [4, None, 2, 1, None]]
def treat_missing_values(table):
for line in table:
for value in line:
if value == None:
value = line[line.index(value)-1]
return table
print treat_missing_values(t)
答案 0 :(得分:4)
这可能是我做的:
>>> def treat_missing_values(table):
... for line in table:
... prev = None
... for i, value in enumerate(line):
... if value is None:
... line[i] = prev
... else:
... prev = value
... return table
...
>>> treat_missing_values([[1, 3, None, 5, None], [2, None, None, 3, 1], [4, None, 2, 1, None]])
[[1, 3, 3, 5, 5], [2, 2, 2, 3, 1], [4, 4, 2, 1, 1]]
>>> treat_missing_values([[None, 3, None, 5, None], [2, None, None, 3, 1], [4, None, 2, 1, None]])
[[None, 3, 3, 5, 5], [2, 2, 2, 3, 1], [4, 4, 2, 1, 1]]
答案 1 :(得分:3)
在python中进行赋值时,只是在内存中的对象上创建引用。您不能使用值来设置列表中的对象,因为您正在有效地将值引用到内存中的另一个对象。
要做你想做的事,你需要直接在右边索引的列表中设置。
如上所述,如果其中一个内部列表中的None为第一个值,则算法将无效。
所以你可以这样做:
t = [[1, 3, None, 5, None], [2, None, None, 3, 1], [4, None, 2, 1, None]]
def treat_missing_values(table, default_value):
last_value = default_value
for line in table:
for index in xrange(len(line)):
if line[index] is None:
line[index] = last_value
else:
last_value = line[index]
return table
print treat_missing_values(t, 0)
答案 2 :(得分:3)
如果列表以None开头或者有重复值,则从值中查找索引的内容将不起作用。试试这个:
def treat(v):
p = None
r = []
for n in v:
p = p if n == None else n
r.append(p)
return r
def treat_missing_values(table):
return [ treat(v) for v in table ]
t = [[1, 3, None, 5, None], [2, None, None, 3, 1], [4, None, 2, 1, None]]
print treat_missing_values(t)
最好不要做你的功课,伙计。
编辑所有FP粉丝的功能版本:
def treat(l):
def e(first, remainder):
return [ first ] + ([] if len(remainder) == 0 else e(first if remainder[0] == None else remainder[0], remainder[1:]))
return l if len(l) == 0 else e(l[0], l[1:])
答案 3 :(得分:1)
我使用全局变量来跟踪最近的有效值。我会使用map()
进行迭代。
t = [[1, 3, None, 5, None], [2, None, None, 3, 1], [4, None, 2, 1, None]]
prev = 0
def vIfNone(x):
global prev
if x:
prev = x
else:
x = prev
return x
print map( lambda line: map( vIfNone, line ), t )
编辑: Malvolio,在这里。很抱歉写下你的答案,但在评论中纠正的错误太多了。
if x:
将失败所有虚假值(特别是0和空字符串)。x
是不必要的; prev
始终具有正确的价值。所以:
def treat(n):
prev = [ None ]
def vIfNone(x):
if x is not None:
prev[0] = x
return prev[0]
return map( vIfNone, n )
(注意将prev作为闭合变量的奇怪用法。它将在treat
的每次调用中是本地的,并且在来自同一{{1}的所有vIfNone调用中是全局的。调用,正是你需要的。对于黑暗和可能令人不安的Python原因,我不明白,它必须是一个数组。)
答案 4 :(得分:0)
<强> EDIT1 强>
# your algorithm won't work if the line start with None
t = [[1, 3, None, 5, None], [2, None, None, 3, 1], [4, None, 2, 1, None]]
def treat_missing_values(table):
for line in table:
for index in range(len(line)):
if line[index] == None:
line[index] = line[index-1]
return table
print treat_missing_values(t)