【问题标题】:Python: Elegant way to iterate over list to fill numpy arrayPython:遍历列表以填充 numpy 数组的优雅方式
【发布时间】:2019-09-03 09:07:05
【问题描述】:

我正在寻找一种更优雅的方式来执行以下操作:

filled_list = [1, 3, 54, 2, 8]
new_list = []

for k in filled_list:
     new_k = # do some stuff
     new_list.append(new_k)

converted_array = np.array(new_list)
  • 遍历列表,但不使用索引
  • 新的 numpy 数组的条目数量与 new_list 中的条目数量完全相同
  • 最后的转换在我看来并不漂亮,我想防止这种情况发生,最好从一个 numpy 数组开始。但是我需要迭代索引,这是我不想要的(因为它使代码更庞大)

编辑:一些东西的例子

# previously filled: dict1, dict2, dict3, common_keys_of_all_dicts

list1 = []
list2 = []
list3 = []
for k in common_keys_of_all_dicts:
   list1.append(dict1[k].item1)
   list2.append(dict2[k].item2)
   list3.append(dict3[k].item3)
array1 = np.array(list1)
...

【问题讨论】:

  • 如果您对# do some fancy stuff 的含义提供一些提示,这可能会更容易回答
  • 在某个步骤或其他步骤中,无论是隐式还是显式,您都必须将列表转换为 numpy 数组,因为您从列表开始。然后的问题是,您是先转换为 numpy 数组,然后 vectorize 进行“花哨的东西”操作,还是坚持当前格式。
  • converted_array = np.fromiter((fancy_stuff(k) for k in filled_list), dtype=...)?如果它是一个 numpy 数组,你为什么说你必须迭代索引?有什么花哨的东西?
  • 笼统地说,您实际上是在采用 numpy 数组的“最坏情况”场景。 numpy 数组的 要点在于它支持向量化(坦率地说,这是一个非常广泛的话题)。因此,如果您必须征求一般性建议,我会说:不要迭代,编写矢量化逻辑,然后您可以从数组开始。如您所见,这很模糊,因为问题本身太宽泛了。请注意,我们无法提供适用于所有情况的矢量化答案,因为这种情况并不总是存在。生成器表达式只是“隐藏”了迭代,但它仍然存在。
  • tl;博士探索矢量化,但没有灵丹妙药。

标签: python numpy


【解决方案1】:

不要将您的起始列表用作列表类型。直接将filled_list 创建为一个numpy 数组,并直接在该数组上执行所有操作。通常所有类型的数学东西都可以直接在数组上完成。 numpy 直接促进了更复杂的事情。如果真的有必要,你可以迭代 numpy 数组。

例如:

filled_list = np.array([1, 2, 3, 4, 5])
result = filled_list * filled_list + 1    #vectorized manipulation

for x in np.nditer(filled_list):          #iteration over array
    x = #do stuff here

我刚刚看到作者添加了一个不适用于初始 numpy-array 的示例。所以这个答案可能已经过时了。

【讨论】:

  • 数组迭代是一种反模式,避免迭代。
  • 没错,但有时您不能将所有内容都放在一个表达式中以进行矢量化数组操作。
  • 为什么推荐nditer?这会做普通for x in filled_list: 做不到的事情吗?
  • 好吧,我从来没有迭代过一个numpy数组,所以我只是在stackoverflow上搜索了它。那是建议的方式。不知道 numpy 数组是否可以像列表一样轻松迭代。
  • 是的,他们可以,@RaJa。
【解决方案2】:

如果没有明确的定义,我会选择:

def somestuff(k):
    return k * 42

converted_array = np.array([somestuff(k) for k in filled_list])

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2014-11-03
    • 2013-07-26
    • 1970-01-01
    • 2023-04-04
    • 2021-05-21
    • 1970-01-01
    • 1970-01-01
    • 2012-07-04
    相关资源
    最近更新 更多