У меня есть функция генератора, которая возвращает пакеты данных x и y.Теперь я хочу написать функцию, которая исчерпывает генератор и складывает его так, чтобы у меня был весь вход и выход моей базы данных в виде 2-х числовых массивов.
Если бы генератор был разделен, следующий кодработа:
import numpy as np
import time
def foo_gen_x(epochs):
for _ in range(epochs):
yield np.array([1, 2])
def foo_gen_y(epochs):
for _ in range(epochs):
yield np.array(["foo"])
start = time.time()
x_epoch = np.vstack(foo_gen_x(100000))
y_epoch = np.vstack(foo_gen_y(100000))
print(x_epoch)
print(y_epoch)
# output x_epoch
# [[1 2]
# ...
# [1 2]]
# output y_epoch
# [['foo']
# ...
# ['foo']]
print("time taken: {}".format(time.time() - start))
# time taken: time taken: 0.6881139278411865
Однако генератор, который у меня есть, выглядит примерно так (возвращает 2 значения):
def foo_gen_xy(epochs):
for _ in range(epochs):
yield np.array([1, 2]), np.array(["foo"])
Попытка 1
Поэтому я попытался что-то написатькак это:
x_epoch, y_epoch = [np.vstack(x), np.vstack(y) for x, y in foo_gen_xy(epochs=4)]
# ValueError: too many values to unpack (expected 2)
Но это дает ValueError
.
Попытка 2
Затем я попробовал более явный подход:
# working but too many lines (and slower?)
start = time.time()
gen = foo_gen_xy(100000)
x_epoch, y_epoch = gen.__next__()
for x, y in gen:
x_epoch = np.vstack((x_epoch, x))
y_epoch = np.vstack((y_epoch, y))
print(x_epoch)
print(y_epoch)
print("time taken: {}".format(time.time() - start))
# time taken: 31.917259454727173
Это примерно в 46 раз медленнее.
Попытка 3
Я мог бы сначала просто сложить все с помощью:
epoch = np.vstack(foo_gen_xy(100000))
# output
# [[array([1, 2]) array(['foo'], dtype='<U3')]
# ...
# [array([1, 2]) array(['foo'], dtype='<U3')]]
Тем не менее, разделение на части выглядит как обходной путь, и этоВведена еще одна проблема, которая меняется dtype
.
Код в блокноте Jupyter
https://colab.research.google.com/drive/1IncrTAosFuQmK65ojmzWV38F8FceL3qt
Вопрос
Что может быть более эффективным способомприменения np.vstack()
к функции-генератору, которая возвращает 2 значения?