如何将列表转换为 numpy 数组以过滤元素?

How can I convert a list to a numpy array for filtering elements?

我有一个 float 数字的列表,我想将它转换为 numpy array 这样我就可以使用 numpy.where() 来获取大于 0.0 的元素的索引(不是零)

我试过了,但没有成功:

import numpy as np

arr = np.asarray(enumerate(grade_list))
g_indices = np.where(arr[1] > 0)[0]

编辑:

需要dtype=float吗?

首先尝试将枚举转换为列表

我做到了:

np.asarray(list(enumerate([1, 2, 3])))

您不需要 enumerate():

arr = np.asarray(grade_list)
g_indices = np.where(arr > 0)[0]

你太复杂了:

import  numpy as np

grade_list_as_array = np.array(grade_list)

您想使用 np.array,而不是 np.asarray,您不需要 enumerate:

import numpy as np

grade_list=[0,1,2,3,2,1,2,3,1,0,2,4]
arr=np.array(grade_list)

g_indices = np.where(arr > 0)[0]

print g_indices

>>> [ 1  2  3  4  5  6  7  8 10 11]

您不需要 numpy 数组来过滤列表。

列出理解

List comprehensions 是一个非常强大的工具,可以编写可读的短代码:

grade_list = [1, 2, 3, 4, 4, 5, 4, 3, 1, 6, 0, -1, 6, 3]
indices = [index for index, grade in enumerate(grade_list) if grade > 0.0]
print(indices)

给出[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 12, 13]。这是一个标准的 Python 列表。如有必要,此列表随后可以转换为 numpy 数组。

Numpy

如果你真的想使用numpy.where,你应该跳过enumerate:

import numpy
grade_list = [1, 2, 3, 4, 4, 5, 4, 3, 1, 6, 0, -1, 6, 3]
grade_list_np = numpy.array(grade_list)
indices = numpy.where(grade_list_np > 0.0)[0]
print(indices)

给出 [ 0 1 2 3 4 5 6 7 8 9 12 13].

性能比较

如果你只需要这个用于一个小列表(例如 < 100),列表理解是最快的方法。使用 numpys where 比先使用列表理解然后将其转换为 numpy 数组(对于 1000 的列表长度)要快得多:

numpy.where (|L| = 1000): 13.5045940876
list_comprehension_np (|L| = 1000): 27.2982738018
list_comprehension (|L| = 1000): 15.2280910015

这些结果是使用以下脚本创建的:

#! /usr/bin/env python
# -*- coding: utf-8 -*-

import random
import timeit
import numpy


def filtered_list_comprehension(grade_list):
    return [index for index, grade in enumerate(grade_list) if grade > 0.3]


def filtered_list_comprehension_np(grade_list):
    return numpy.array([index for index, grade in enumerate(grade_list)
                        if grade > 0.3])


def filtered_numpy(grade_list):
    grade_list_np = numpy.array(grade_list)
    return numpy.where(grade_list_np > 0.3)[0]

list_elements = 10000
grade_list = [random.random() for i in range(list_elements)]

res = timeit.timeit('filtered_numpy(grade_list)',
                    number=100000,
                    setup="from __main__ import grade_list, filtered_numpy")
print("numpy.where (|L| = %i): %s" % (list_elements, str(res)))
res = timeit.timeit('filtered_list_comprehension_np(grade_list)',
                    number=100000,
                    setup="from __main__ import grade_list, filtered_list_comprehension_np")
print("list_comprehension_np (|L| = %i): %s" % (list_elements, str(res)))
res = timeit.timeit('filtered_list_comprehension(grade_list)',
                    number=100000,
                    setup="from __main__ import grade_list, filtered_list_comprehension")
print("list_comprehension (|L| = %i): %s" % (list_elements, str(res)))

enumerate 是多余的。如果你真的有一个浮动列表,这将起作用:

import numpy as np 
arr = np.array(grade_list)
g_indices = np.where(arr > 0)[0]

由于在数字的布尔比较中,0.0 的计算结果为 False,从技术上讲,您也可以省略 >0

但是如果您有嵌套列表或元组列表,则不会。我们可能需要更多地了解您的列表。