迭代多个数组来执行任务?
Iterate over multiple arrays to perform tasks?
我有 9 个数组,每个数组包含 19 个值。
假设它们是 a1,a2,a3,a4,a5,a6,a7,a8,a9
(每个 a1、a2...a9 都包含 19 个值),我们称它们为 a
数组。
我还有 9 个数组,每个数组包含 19 个值。
假设它们是 b1,b2,b3,b4,b5,b6,b7,b8,b9
(每个 b1、b2...b9 都包含 19 个值),我们称它们为 b
数组。
我现在想获取每个a
数组的第一个值 和每个 b
数组的第一个值,除他们 (a/b)
,这将给我一个新数组,假设 a/b
有 19 个值。然后我使用 numpy.std
计算这 19 个值的标准差。
然后我想再次遍历这些数组,但是 这次是每个数组的第二个值 依此类推直到最后一个(第 19 个)值并执行上述操作手术。
如果我只有 2 个数组(比如 a1
和 b1
),我可以使用 zip
,例如:
div_array = [] # The empty array that will have the divided values
for a,b in zip(a1,b1):
div = a/b
div_array.append(div)
std = np.std(div_array)
如何在冗长的案例中重复上述内容?
编辑:
我最终需要 19 个不同的标准差, 即我计算第一个值,然后是第二个值,依此类推。
您可以将每个 a
和 b
数组放在另一个数组中。所以会是
a[0] = a1
、a[1] = a2
等 b
也是如此
然后像这样:
for i in range(length(a)):
div_array = []
for j in range(length(a[i])):
div = a[i][j]/b[i][j]
div_array.append(div)
std.append(np.std(div_array))
然后你有一个数组std
,其中包含你想要的所有值。
当然,如果 a
和 b
的长度相同并且 a[0]
和 b[0]
等的长度也相同,那将起作用。你的情况是这样。
不久前我写了一篇 class 基本上可以满足您的要求。唯一的技巧是您必须向 class 传递每个数组的迭代器列表。
column_iter_traversal.py
"""
This code will take in a iterator of iterators. You can view the first
iterator as the rows of a graph (a matrix being a specific case of graphs)
and each iterable giving you the columns (or nodes) of that graph.
so if you have a graph
[[1, 2],
[3],
[4, 5]]
we'd expect the iterator to return [1, 3, 4, 2, 5]
"""
class ColumnTraversalIter():
"""
This is a class which is used to contain the currently travered state.
This is the class which defines the returned object for
column_traversal_iter. The iter that function returns is an instance of
this class.
"""
def __init__(self, iter_of_iters):
# Build a list of iterators
self.iter_list = []
for it in iter_of_iters:
self.iter_list.append(it)
self.current_iter_index = 0
def __iter__(self):
return self
def __next__(self):
# Get the next value from the current iterator
try:
return_val = next(self.iter_list[self.current_iter_index])
self.current_iter_index = self._increment_index(
self.current_iter_index,
len(self.iter_list))
return return_val
except StopIteration:
# When we run into a stop iteration we know that the current
# iterator is out of values. Remove the current iterator from
# the iterator list.
del self.iter_list[self.current_iter_index]
# If we are out of iterators it's time to raise StopIteration
if len(self.iter_list) == 0:
raise StopIteration
else:
# Otherwise, set the current_iter_index and recall next
self.current_iter_index = self._increment_index(
self.current_iter_index,
len(self.iter_list))
return self.__next__()
except IndexError:
# Someone called __next__ when there aren't any iterators left in
# the iter_list.
raise StopIteration
@staticmethod
def _increment_index(iter_index, wrap_length):
if iter_index + 1 > wrap_length:
print("returning 0")
return 0
else:
print("returning {}".format(iter_index + 1))
return iter_index + 1
def column_traversal_iter(iter_of_iters):
"""
args:
iterator: a iterator of iterators. If there aren't any iterators or
there are non iterator elements this will explode.
returns a COlumnTraversalIter
"""
return ColumnTraversalIter(iter_of_iters)
tests.py
import unittest
from column_traversal import column_traversal_iter
class TestBruteforceImplemetation(unittest.TestCase):
def test_no_iters(self):
test_iter = iter([])
column_iter = column_traversal_iter(test_iter)
with self.assertRaises(StopIteration):
next(column_iter)
def test_iter_of_one_empty_iter(self):
"""
One empty iter and many empty iters should hit one stop iteration.
"""
test_iter = iter([iter([])])
column_iter = column_traversal_iter(test_iter)
with self.assertRaises(StopIteration):
next(column_iter)
def test_iter_of_many_empty_iter(self):
"""
One empty iter and many empty iters should hit one stop iteration.
"""
test_iter = iter([iter([]), iter([]), iter([])])
column_iter = column_traversal_iter(test_iter)
with self.assertRaises(StopIteration):
next(column_iter)
def test_iter_simple_one_by_one_matrix(self):
"""
One empty iter and many empty iters should hit one stop iteration.
"""
test_iter = iter([iter([1]), iter([2]), iter([3])])
column_iter = column_traversal_iter(test_iter)
expected_traversal = [1, 2, 3]
for actual_value, expected_value in zip(column_iter, expected_traversal):
self.assertEqual(actual_value, expected_value)
# Check to make sure there's a stop iteration.
with self.assertRaises(StopIteration):
next(column_iter)
def test_iter_simple_jagged_graph(self):
"""
One empty iter and many empty iters should hit one stop iteration.
"""
test_iter = iter([iter([1]), iter([2, 4]), iter([3])])
column_iter = column_traversal_iter(test_iter)
expected_traversal = [1, 2, 3, 4]
for actual_value, expected_value in zip(column_iter, expected_traversal):
self.assertEqual(actual_value, expected_value)
# Check to make sure there's a stop iteration.
with self.assertRaises(StopIteration):
next(column_iter)
def test_iter_simple_two_by_two_matrix(self):
"""
One empty iter and many empty iters should hit one stop iteration.
"""
test_iter = iter([iter([1, 4]), iter([2, 5]), iter([3, 6])])
column_iter = column_traversal_iter(test_iter)
expected_traversal = [1, 2, 3, 4, 5, 6]
for actual_value, expected_value in zip(column_iter, expected_traversal):
self.assertEqual(actual_value, expected_value)
# Check to make sure there's a stop iteration.
with self.assertRaises(StopIteration):
next(column_iter)
def test_iter_one_iter_is_blank(self):
"""
One empty iter and many empty iters should hit one stop iteration.
"""
test_iter = iter([iter([1, 3]), iter([2, 4]), iter([])])
column_iter = column_traversal_iter(test_iter)
expected_traversal = [1, 2, 3, 4]
for actual_value, expected_value in zip(column_iter, expected_traversal):
self.assertEqual(actual_value, expected_value)
# Check to make sure there's a stop iteration.
with self.assertRaises(StopIteration):
next(column_iter)
并且您将通过
使用此代码
divisor_iter_list = []
for a_list in a_lists:
divisor_iter_list.append(iter(a_list))
dividend_iter_list = []
for b_list in b_lists:
divident_iter_list.append(iter(b_list))
divisor_iter = ColumnTraversalIter(divisor_iter_list)
dividend_iter = ColumnTraversalIter(divident_iter_list)
for divisor, dividend in zip(divisor_iter, dividend_iter):
# Do calculations.
如果你要用 std
,为什么不用 numpy
的幂来做除法?
>>> # You can create these array in a loop if you want
>>> a = np.array([a1, a2, a3, ..., a9])
>>> b = np.array([b1, b2, b3, ..., b9])
>>> c = np.std(a / b, 0)
示例(包含有关 np.std
的详细信息):
>>> a1 = np.array([1, 2, 3])
>>> a2 = np.array([2, 3, 4])
>>> a = np.array([a1, a2])
>>> a
array([[1, 2, 3],
[2, 3, 4]])
>>> b1 = np.array([10, 100, 1000])
>>> b2 = np.array([20, 200, 2000])
>>> b = np.array([b1, b2])
>>> b
array([[10, 100, 1000],
[20, 200, 2000]])
>>> a/b
array([[0.1, 0.02, 0.003],
[0.1, 0.015, 0.002]])
>>> np.std(a/b) # The standard deviation of the whole matrix
0.04289...
>>> np.std(a/b, 0) # The standard deviation of each column
array([0, 0.0025, 0.0005])
>>> np.std(a/b, 1) # The standard deviation of each row
array([0.04229263, 0.04345879])
我有 9 个数组,每个数组包含 19 个值。
假设它们是 a1,a2,a3,a4,a5,a6,a7,a8,a9
(每个 a1、a2...a9 都包含 19 个值),我们称它们为 a
数组。
我还有 9 个数组,每个数组包含 19 个值。
假设它们是 b1,b2,b3,b4,b5,b6,b7,b8,b9
(每个 b1、b2...b9 都包含 19 个值),我们称它们为 b
数组。
我现在想获取每个a
数组的第一个值 和每个 b
数组的第一个值,除他们 (a/b)
,这将给我一个新数组,假设 a/b
有 19 个值。然后我使用 numpy.std
计算这 19 个值的标准差。
然后我想再次遍历这些数组,但是 这次是每个数组的第二个值 依此类推直到最后一个(第 19 个)值并执行上述操作手术。
如果我只有 2 个数组(比如 a1
和 b1
),我可以使用 zip
,例如:
div_array = [] # The empty array that will have the divided values
for a,b in zip(a1,b1):
div = a/b
div_array.append(div)
std = np.std(div_array)
如何在冗长的案例中重复上述内容?
编辑:
我最终需要 19 个不同的标准差, 即我计算第一个值,然后是第二个值,依此类推。
您可以将每个 a
和 b
数组放在另一个数组中。所以会是
a[0] = a1
、a[1] = a2
等 b
然后像这样:
for i in range(length(a)):
div_array = []
for j in range(length(a[i])):
div = a[i][j]/b[i][j]
div_array.append(div)
std.append(np.std(div_array))
然后你有一个数组std
,其中包含你想要的所有值。
当然,如果 a
和 b
的长度相同并且 a[0]
和 b[0]
等的长度也相同,那将起作用。你的情况是这样。
不久前我写了一篇 class 基本上可以满足您的要求。唯一的技巧是您必须向 class 传递每个数组的迭代器列表。
column_iter_traversal.py
"""
This code will take in a iterator of iterators. You can view the first
iterator as the rows of a graph (a matrix being a specific case of graphs)
and each iterable giving you the columns (or nodes) of that graph.
so if you have a graph
[[1, 2],
[3],
[4, 5]]
we'd expect the iterator to return [1, 3, 4, 2, 5]
"""
class ColumnTraversalIter():
"""
This is a class which is used to contain the currently travered state.
This is the class which defines the returned object for
column_traversal_iter. The iter that function returns is an instance of
this class.
"""
def __init__(self, iter_of_iters):
# Build a list of iterators
self.iter_list = []
for it in iter_of_iters:
self.iter_list.append(it)
self.current_iter_index = 0
def __iter__(self):
return self
def __next__(self):
# Get the next value from the current iterator
try:
return_val = next(self.iter_list[self.current_iter_index])
self.current_iter_index = self._increment_index(
self.current_iter_index,
len(self.iter_list))
return return_val
except StopIteration:
# When we run into a stop iteration we know that the current
# iterator is out of values. Remove the current iterator from
# the iterator list.
del self.iter_list[self.current_iter_index]
# If we are out of iterators it's time to raise StopIteration
if len(self.iter_list) == 0:
raise StopIteration
else:
# Otherwise, set the current_iter_index and recall next
self.current_iter_index = self._increment_index(
self.current_iter_index,
len(self.iter_list))
return self.__next__()
except IndexError:
# Someone called __next__ when there aren't any iterators left in
# the iter_list.
raise StopIteration
@staticmethod
def _increment_index(iter_index, wrap_length):
if iter_index + 1 > wrap_length:
print("returning 0")
return 0
else:
print("returning {}".format(iter_index + 1))
return iter_index + 1
def column_traversal_iter(iter_of_iters):
"""
args:
iterator: a iterator of iterators. If there aren't any iterators or
there are non iterator elements this will explode.
returns a COlumnTraversalIter
"""
return ColumnTraversalIter(iter_of_iters)
tests.py
import unittest
from column_traversal import column_traversal_iter
class TestBruteforceImplemetation(unittest.TestCase):
def test_no_iters(self):
test_iter = iter([])
column_iter = column_traversal_iter(test_iter)
with self.assertRaises(StopIteration):
next(column_iter)
def test_iter_of_one_empty_iter(self):
"""
One empty iter and many empty iters should hit one stop iteration.
"""
test_iter = iter([iter([])])
column_iter = column_traversal_iter(test_iter)
with self.assertRaises(StopIteration):
next(column_iter)
def test_iter_of_many_empty_iter(self):
"""
One empty iter and many empty iters should hit one stop iteration.
"""
test_iter = iter([iter([]), iter([]), iter([])])
column_iter = column_traversal_iter(test_iter)
with self.assertRaises(StopIteration):
next(column_iter)
def test_iter_simple_one_by_one_matrix(self):
"""
One empty iter and many empty iters should hit one stop iteration.
"""
test_iter = iter([iter([1]), iter([2]), iter([3])])
column_iter = column_traversal_iter(test_iter)
expected_traversal = [1, 2, 3]
for actual_value, expected_value in zip(column_iter, expected_traversal):
self.assertEqual(actual_value, expected_value)
# Check to make sure there's a stop iteration.
with self.assertRaises(StopIteration):
next(column_iter)
def test_iter_simple_jagged_graph(self):
"""
One empty iter and many empty iters should hit one stop iteration.
"""
test_iter = iter([iter([1]), iter([2, 4]), iter([3])])
column_iter = column_traversal_iter(test_iter)
expected_traversal = [1, 2, 3, 4]
for actual_value, expected_value in zip(column_iter, expected_traversal):
self.assertEqual(actual_value, expected_value)
# Check to make sure there's a stop iteration.
with self.assertRaises(StopIteration):
next(column_iter)
def test_iter_simple_two_by_two_matrix(self):
"""
One empty iter and many empty iters should hit one stop iteration.
"""
test_iter = iter([iter([1, 4]), iter([2, 5]), iter([3, 6])])
column_iter = column_traversal_iter(test_iter)
expected_traversal = [1, 2, 3, 4, 5, 6]
for actual_value, expected_value in zip(column_iter, expected_traversal):
self.assertEqual(actual_value, expected_value)
# Check to make sure there's a stop iteration.
with self.assertRaises(StopIteration):
next(column_iter)
def test_iter_one_iter_is_blank(self):
"""
One empty iter and many empty iters should hit one stop iteration.
"""
test_iter = iter([iter([1, 3]), iter([2, 4]), iter([])])
column_iter = column_traversal_iter(test_iter)
expected_traversal = [1, 2, 3, 4]
for actual_value, expected_value in zip(column_iter, expected_traversal):
self.assertEqual(actual_value, expected_value)
# Check to make sure there's a stop iteration.
with self.assertRaises(StopIteration):
next(column_iter)
并且您将通过
使用此代码divisor_iter_list = []
for a_list in a_lists:
divisor_iter_list.append(iter(a_list))
dividend_iter_list = []
for b_list in b_lists:
divident_iter_list.append(iter(b_list))
divisor_iter = ColumnTraversalIter(divisor_iter_list)
dividend_iter = ColumnTraversalIter(divident_iter_list)
for divisor, dividend in zip(divisor_iter, dividend_iter):
# Do calculations.
如果你要用 std
,为什么不用 numpy
的幂来做除法?
>>> # You can create these array in a loop if you want
>>> a = np.array([a1, a2, a3, ..., a9])
>>> b = np.array([b1, b2, b3, ..., b9])
>>> c = np.std(a / b, 0)
示例(包含有关 np.std
的详细信息):
>>> a1 = np.array([1, 2, 3])
>>> a2 = np.array([2, 3, 4])
>>> a = np.array([a1, a2])
>>> a
array([[1, 2, 3],
[2, 3, 4]])
>>> b1 = np.array([10, 100, 1000])
>>> b2 = np.array([20, 200, 2000])
>>> b = np.array([b1, b2])
>>> b
array([[10, 100, 1000],
[20, 200, 2000]])
>>> a/b
array([[0.1, 0.02, 0.003],
[0.1, 0.015, 0.002]])
>>> np.std(a/b) # The standard deviation of the whole matrix
0.04289...
>>> np.std(a/b, 0) # The standard deviation of each column
array([0, 0.0025, 0.0005])
>>> np.std(a/b, 1) # The standard deviation of each row
array([0.04229263, 0.04345879])