簡體   English   中英

在循環中創建NumPy數組的最有效,最Python方式

[英]Most efficient and most pythonic way to create a NumPy array within a loop

我目前正在嘗試找出在循環中創建numpy數組的最有效方法,以下是示例:

import numpy as np
from time import time
tic = time()
my_list = range(1000000)
a = np.zeros((len(my_list),))
for i in my_list:
   a[i] = i
toc = time()
print(toc-tic)

tic = time()
a = []
my_list = range(1000000)
for i in my_list:
    a.append(i)
a = np.array(a)
toc = time()

print(toc-tic)

我期望第二個比第一個慢很多,因為在for循環的每一步都需要新的內存,但是這些大致相同,我想知道為什么,但是出於好奇,因為我可以兩者都做。

我實際上想編寫一個簡單的numpy數組,其中包含從數據幀中提取的數據,看起來很亂。 我想知道是否會有更pythonic的方式來做到這一點。 我有此數據框和所需的標簽列表,最簡單的想法是執行以下操作(我需要的值是每列的最后一個):

vars_outputs = ["x1", "x2", "ratio_x1_x2"]
my_df = pd.read_excel(path)
outpts = np.array(my_df[vars_outputs][-1])

但是,這是不可能的,因為我想要的某些標簽在數據幀中不直接可用:例如,ratio_x1_x2需要從前兩列開始計算。 因此,我添加了一個缺少標簽的字典以及計算它們的方法(這是唯一的比率):

missing_labels = {"ratio_x1_x2" : ["x1", "x2"]}

並檢查條件並創建numpy數組(因此前面的效率問題)

outpts = []
for var in vars_outputs:
    if var in missing_labels.keys():
        outpts.append(my_df[missing_labels[var][0]][-1]/my_df[missing_labels[var][1]][-1])
    else:
        outpts.append(my_df[var][-1])
outpts = np.array(outpts)

在我看來,這似乎太復雜了,但我想不出一種更簡單的方法(尤其是因為我需要在numpy輸出數組中具有此特定順序)

我的另一個想法是使用所需的操作在數據幀中添加列,但是由於大約有8000個標簽,我不知道這是最好的方法,因為在此預處理步驟之后,我將不得不查看所有這些標簽

非常感謝

這是最終的代碼,np.fromiter()可以解決問題,並允許通過使用列表理解來減少行數

df = pd.read_excel(path)
print(df.columns)

輸出['x1','x2']

vars_outputs = ["x1", "x2", "ratio_x1_x2"]
missing_labels = {"ratio_x1_x2" : ["x1", "x2"]}

it = [df[missing_labels[var][0]].iloc[-1]/df[missing_labels[var][1]].iloc[-1] if var in missing_labels
        else df[var].iloc[-1] for var in vars_outputs]

t = np.fromiter(it, dtype = float)

謝謝@hpaulj,這將來可能對我很有用。 我不知道使用fromiter()的速度

import timeit
setup = '''
import numpy as np
H, W = 400, 400
it = [(1 + 1 / (i + 0.5)) ** 2 for i in range(W) for j in range(H)]'''

fns = ['''
x = np.array([[(1 + 1 / (i + 0.5)) ** 2 for i in range(W)] for j in range(H)])
''', '''
x = np.fromiter(it, np.float)
x.reshape(H, W)
''']
for f in fns:
  print(timeit.timeit(f,setup=setup, number=100))
# gives me
# 6.905218548999983
# 0.5763416080008028

編輯PS您的for循環可能是某種迭代器,例如

it = [my_df[missing_labels[var][0]][-1]
        / my_df[missing_labels[var][1]][-1] if var in missing_labels
        else my_df[var][-1] for var in var_outputs]

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM