2015-07-01 3 views
0

У меня есть 9 массивов, каждый из которых содержит 19 значений.Python, перебирать несколько массивов для выполнения задач

Допустит, они 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 значениями. Затем я вычисляю стандартное отклонение этих 19 значений, используя numpy.std.

Затем я хочу снова повторить эти массивы, но на этот раз второй значением каждого из этих массивов и так далее до последнего (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) 

Как повторить выше в моем случае длительного ??

EDIT:

я наконец нужно 19 различных стандартных отклонений, т.е. рассчитать его для первых значений, то вторые значения и так далее ..

+0

вам не нравится 'для я в диапазоне (0, длина (а)): сделать [I]' синтаксис. Вы? – deathangel908

+0

@ deathangel908: Итак, 'a' здесь относится к массиву, содержащему все мои' a1, a2 ... a9'? – ThePredator

+1

yep, я бы просто использовал текущий индекс элемента. 'a [i], b [i], c [i]' и т. д. Но, может быть, есть лучший способ. – deathangel908

ответ

5

Почему бы не использовать возможности numpy для разделения, если вы используете его для std?

>>> # 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]) 
+0

Мне, наконец, нужно 19 различных стандартных отклонений, т. Е. Я рассчитываю его для первых значений, затем для вторых значений и т. Д. Выше, кажется, дает мне 1 стандартное отклонение. Можете ли вы объяснить, что означает '0' в' c = np.std (a/b, 0) '? – ThePredator

+1

Это ось, по которой вычисляется стандартное отклонение. Оси определены для массивов с более чем одним измерением. 2-мерный массив имеет две соответствующие оси: первая выполняется вертикально вниз по строкам (ось 0), а вторая выполняется горизонтально по столбцам (ось 1). – Matt

+0

@ ThePredator Вышеуказанное дает вам 19 стандартных стандартных отклонений, проверьте форму 'c'. – Holt

0

Вы могли бы каждый a и b массив в другом массиве. Поэтому было бы

а [0] = a1, а [1] = a2 и т.д. samething для 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] и так далее имеют одинаковую длину и. Это верно в вашем случае.

+0

Я хотел бы иметь стандартные отклонения для каждого из 19 значений отдельно. Означает ли это выше? Я вижу, что мы добавляем все 'div_array' в один список' std' – ThePredator

+0

Да, это ошибка, вам нужно очистить 'div_array', я только что исправил это сейчас. Я не тестировал его, но вы можете попробовать, он должен быть быстрым, чтобы проверить, не так ли? – ArianJM

+0

Ну, это еще не все, что мне нужно! – ThePredator

0

Итак, я написал класс, который по сути делает то, о чем вы просите. Единственный трюк в том, что вам придется передать классу список итераторов для каждого массива.

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. 
Смежные вопросы