以最高效的方式处理内层列表中的第一个项目

7

我在Python中有一个协调存储列表A[row,col,value],用于存储非零值。

如何获取所有行索引的列表?我期望这个A[0:][0]可以像print A[0:]一样工作,因为print A[0:]打印整个列表,但是print A[0:][0]只打印A[0]

我提出这个问题是为了高效计算每行的非零值数量,即迭代range(0,n),其中n是总行数。这应该比我的当前方式for i in range(0,n): for j in A: ...更加便宜。

类似这样:

c = []
# for the total number of rows
for i in range(0,n):
     # get number of rows with only one entry in coordinate storage list
     if A[0:][0].count(i) == 1: c.append(i)                
return c

关于:

c = []
# for the total number of rows 
for i in range(0,n):
    # get the index and initialize the count to 0 
    c.append([i,0])
    # for every entry in coordinate storage list 
    for j in A:
        # if row index (A[:][0]) is equal to current row i, increment count  
        if j[0] == i:
           c[i][1]+=1
return c

编辑:

根据Junuxx的回答,在这个问题这篇文章的帮助下,我得到了以下代码(用于返回单行出现的次数),对于我当前A的问题规模要比我的原始尝试更快。但是它仍然随着行列数的增加而增长。我想知道是否可能不必迭代整个A而只需迭代到n

# get total list of row indexes from coordinate storage list
row_indexes = [i[0] for i in A]
# create dictionary {index:count}
c = Counter(row_indexes)    
# return only value where count == 1 
return [c[0] for c in c.items() if c[1] == 1]

1
@larsman:我假设A是一个三元组列表。 - Junuxx
1
你能否写一个简单、低效但可工作的示例来说明你想做什么吗?我觉得问题的措辞真的很令人困惑,而且你提供的代码块似乎都没有做同样的事情..? - dbr
我正在计算包含仅一个非零值的所有行,这些行来自坐标存储列表。第二个代码块略有不同,因为它返回每行的计数。我已经更新了带有注释的代码。 - Chris Seymour
2个回答

16
这应该就可以了:

这样做应该就可以了:

c = [x[0] for x in A]

这是一个列表推导,它获取A的每个元素的第一个子元素。


这个方案的性能比我的原始解决方案要好得多。请看我的编辑,是否可能不遍历A?非常感谢! - Chris Seymour
如果A非常大,但是A的元素仅有三个成员,那么将三个列表rows、columns和values存储起来可能更有效。您可以立即获取所有行号,并且仍然可以使用相同的索引访问单个条目(它们已对齐)。如果A和子列表都很长,最好使用numpy提供的真正的二维数据结构(请参见Jon Clements的答案),而不是嵌套列表。 - Junuxx

4

为了提高效率和进行扩展切片,你可以使用 numpy - 根据你的示例看起来是个不错的选择:

import numpy as np
yourlist = [
    [0, 0, 0],
    [0, 1, 1],
    [1, 0, 2]
]
a = np.array(yourlist)
print a[:,0]
# [0 0 1]
bc = np.bincount(a[:,0])
# array([2, 1])
count = bc[bc==1].size
# 1
# or... (I think it's probably better...)
count = np.count_nonzero(bc == 1)

我无法使您的示例运行起来。 type(mylist[0][0]) 返回 inttype(a[0][0])a = numpy.array(mylist) 后返回 numpy.float64,当我尝试 bincount(a[:,0]) 时,我得到了 TypeError: array cannot be safely cast to required type 错误。我尝试过 bc = numpy.bincount(numpy.arange( a[:,0],dtype=numpy.int)),但是出现了错误 TypeError: only length-1 arrays can be converted to Python scalars - Chris Seymour
@sudo_o 对此我不太清楚 - 在 np.array(而不是 np.arange)之后,我得到了 type(a[0][0]) <type 'numpy.int32'>,然后其他一切都正常运行... - Jon Clements

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接