рассчитать среднее значение вложенного массива определенным образом с помощью Python? - PullRequest
1 голос
/ 28 октября 2019

Мне нужен способ для вычисления среднего значения вложенного массива (четного или нечетного) следующим образом:

допустим, у нас есть этот массив (список) (четный 4 * 4):

mylist = [
[1,6,5,6],
[2,5,6,8],
[7,2,8,1],
[4,4,7,3]
] 

вывод должен быть таким:

mylist = [[3,6],
[4,4]
]

на основе этого вычисления

1 + 6 + 2 + 5 / 4 = 3
5 + 6 + 6 + 8 / 4 = 6
7 + 2 + 4 + 4 / 4 = 4
8 + 1 + 7 + 3 / 4 = 4

то же самое, если у нас есть нечетный вложенный массив, подобный этому

mylist = [[7,9,1],
[4,2,1],
[3,2,3]]

результат будет:

mylist = [[5,1],
[2,3]
]

на основе того же вычисления, что и выше ..

7 + 9 + 4 + 2 / 4 = 5
1 + 1 / 2 = 1
3 + 2 / 2 = 2
3 / 1 = 3

, так как мы можем реализовать этот процесс с помощью Python, обратите внимание, что я знаю, каксделать нормальное среднее значение для каждого массива, например, просто увеличивая числа для каждого массива построчно и деля их на число ..

 mylist = [[70,80,90],
[30,40,50],
[0,10,20],
[10,40,40]]
avglist = []
for x in mylist:
    temp = 0
    counter = 0
    for y in x:     
        temp = temp + y
        counter = counter + 1
    avglist.append(temp/counter)
    print()
print()
print(avglist)

но в этой проблеме .. я сталкиваюсь с проблемой, как перейти кзатем следующий массив возвращается к первому массиву и т. д. ....

**

обратите внимание: это должен быть квадратный массив (длина строки = длина столбца)

**

Ответы [ 3 ]

1 голос
/ 28 октября 2019

Хорошо, вот моя попытка. Это немного многословно, но я думаю, что за ним очень легко следовать.

# helper func to split nested list (NxN matrix) into 4 quadrants
def split_mat(mat):
    n = len(mat)
    s = math.ceil(n/2)
    up_left  = [mat[i][j] for i in range(0, s) for j in range(0, s)]
    up_right = [mat[i][j] for i in range(0, s) for j in range(s, n)]
    bt_left  = [mat[i][j] for i in range(s, n) for j in range(0, s)]
    bt_right = [mat[i][j] for i in range(s, n) for j in range(s, n)]
    return [up_left, up_right, bt_left, bt_right]

# then the averages you want to calculate becomes trivial
def avg_mat(mat):  
    quadrants = split_mat(mat)
    avgs = [sum(q)//len(q) for q in quadrants]
    return [[avgs[0], avgs[1]], [avgs[2], avgs[3]]]
even_list = [
[1,6,5,6],
[2,5,6,8],
[7,2,8,1],
[4,4,7,3]]

print(avg_mat(even_list))
--------------------------------------------------
[[3, 6], [4, 4]]
odd_list = [
[7,9,1],
[4,2,1],
[3,2,3]]

print(avg_mat(odd_list))
--------------------------------------------------
[[5, 1], [2, 3]]
1 голос
/ 28 октября 2019

Немного гольфы, извините, печатать на телефоне означает короткие имена :). Я использую преимущество целочисленного деления для простой логики и использую итоги плюс деление по промежуточным спискам.

from itertools import product

def quad_avgs(M):
  sums = [[0,0],[0,0]]
  L, S, s = len(M), len(M) / 2, len(M) - len(M) / 2
  for r, c in product(range(L), repeat=2):
      sums[r / S][c / S] += M[r][c]
  return [[sums[r][c] / ([S, s][r] * [S, s][c]) for c in [0, 1]] for r in [0, 1]]
0 голосов
/ 28 октября 2019

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

Предполагая, что мы всегда вычисляем четыре числа (суммы каждого квадранта, с смещением в сторону верхнего левого квадранта, если размеры неравны), мы можем просто подготовить их заранее, а затем просканировать каждую ячейкуматрицы, определите, в каком квадранте он находится, и увеличьте сумму:

def calculation(matrix):
    # prepare empty lists for each quadrant
    # we will add each element from the matrix to the list that corresponds to its quadrant
    # then at the end we will take the average of each.
    sums = {
        (True, True):   [],  # top-left
        (True, False):  [],  # top-right
        (False, True):  [],  # bottom-left
        (False, False): [],  # bottom-right
    }
    # scan over each cell by row and column index
    for row in range(len(matrix)):
        for col in range(len(matrix[row])):
            # use boolean checks to index into sums depending on quadrant
            sums[(row < len(matrix) / 2,      # is it in the top half?
                  col < len(matrix[row]) / 2  # is it in the left half?
                )].append(matrix[row][col])
    # calculate and return averages (using integer division instead of true division)
    return [[sum(sums[True, True])   // len(sums[True, True]),     # top-left
             sum(sums[True, False])  // len(sums[True, False])],   # top-right
            [sum(sums[False, True])  // len(sums[False, True]),    # bottom-left
             sum(sums[False, False]) // len(sums[False, False])]]  # bottom-right

Контрольные примеры:

>>> mylist = [
... [1,6,5,6],
... [2,5,6,8],
... [7,2,8,1],
... [4,4,7,3]
... ] 
>>> calculation(mylist)
[[3, 6], [4, 4]]

>>> mylist = [[7,9,1],
... [4,2,1],
... [3,2,3]]
>>> calculation(mylist)
[[5, 1], [2, 3]]
...