【问题标题】:Select items of certain indices from a list of lists fast快速从列表列表中选择某些索引的项目
【发布时间】:2019-03-15 14:49:34
【问题描述】:

我在 Python 版本:2.7.12 |Anaconda 4.1.1(64 位)| (默认,2016 年 6 月 29 日,11:07:13)[MSC v.1500 64 位 (AMD64)]

我有一个表作为列表列表,比如“表”,第一个唯一元素列表是标题和一个列表,比如“cols”和一些表列。我想看看是否有比下面更快的方法来选择与 cols 的项目相对应的每个表列表的项目:

def select_cols(table, cols):
    inds = [table[0].index(col) for col in cols]
    return [[row[i] for i in inds] for row in table]

例子:

table = [['a','b','c','d'],[1,2,3,4],[5,6,7,8]]
cols = ['b','d']
print select_cols(table, cols)
>>[['b', 'd'], [2, 4], [6, 8]]

实际上我已经制作了一个应用程序,它通过读取大的 csv 文件来制作这些表,并以这种方式进行大量切片,所以我希望这个函数尽可能快地运行。此外,我不想在这项工作中使用 pandas,因为我想让应用程序保持轻便。

【问题讨论】:

  • 只要使用内置的csv模块
  • 具体来说,DictReader 可能有用:docs.python.org/2/library/csv.html#csv.DictReader
  • 实际上数据也可能来自其他类型的文件,所以让我们考虑一下我们有一个列表列表作为表格和一个列列表供选择,我们尝试找到最快的方法去做
  • 您的问题中是否还有其他限制/信息?
  • 没有。它说得很好。谢谢!

标签: python python-2.7


【解决方案1】:

您可以使用运算符itemgetter() 从子列表中获取元素:

from operator import itemgetter

def select_cols(table, cols):
    cols_ = set(cols)
    inds = []

    # get indices of selected elements
    for num, i in enumerate(table[0]):
        if i in cols_:
            inds.append(num)

    # get sublists with selected elements
    iget = itemgetter(*inds)
    return [iget(i) for i in table]

您也可以使用函数compress()

from itertools import compress

def select_cols(table, cols):
    cols_ = set(cols)

    # build selector list
    sel = [i in cols_ for i in table[0]]

    # get sublists with selected elements
    return [list(compress(i, sel)) for i in table]

【讨论】:

  • 在计时所有选项后,我们从快到慢:1)itemgettr 2)压缩 3)挖掘 4)映射。坏事是,如果你想从 itemgetter 获得相同类型的输出(当 cols 有一个项目时,它不会返回元组列表),你必须在 item getter 上使用闭包,这样你会失去一些速度但是相对于其他选项,它仍然保持在同一个位置。另一个有趣的事情是,将 cols 转换为 set 比将其保留为列表并使用列表推导来定义 inds 或 sel 对我来说不是那么直观...
【解决方案2】:

您可以使用zip 函数对行中的列进行分组,通过仅保留cols 中的列来过滤列,然后再次zip 列组以获得行中的结果。 map 行到list 如果您希望行作为列表而不是元组:

map(list, zip(*(columns for columns in zip(*table) if columns[0] in cols)))

这会返回:

[['b', 'd'], [2, 4], [6, 8]]

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2019-04-18
    • 2011-08-10
    • 1970-01-01
    • 2013-05-28
    • 2016-03-27
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多