Как найти наиболее часто встречающийся прогрессивный di git из списка 4-значных чисел - PullRequest
1 голос
/ 08 мая 2020

Я новичок в программировании Python. Какой эффективный и Pyhtoni c способ найти наиболее частый прогрессивный di git из списка 4-значных чисел?

Допустим, у меня есть следующий список: [6111, 7111, 6112, 6121, 6115, 6123].

Лог c означает, что для первого di git 6 является наиболее частым. Я могу исключить число 7111 для следующих размышлений.

Для второго di git я рассматриваю новых кандидатов [6111, 6112, 6121, 6115, 6123] и замечаю, что 1 является наиболее частым di git и так далее.

В конце алгоритм, у меня останется только 1 номер из списка.

Если есть 2 или более номеров с одинаковыми вхождениями для di git, я могу выбрать меньшее из случайных чисел между всеми их.

Простым подходом могло бы быть преобразование списка в матрицу Nx4 и рассмотрение для каждого столбца наиболее частого di git. Это могло сработать, но я нашел очень глупый и неэффективный способ решить эту проблему. Может ли кто-нибудь помочь?

ИЗМЕНИТЬ: мой код для этого решения (ПРИМЕЧАНИЕ: ЭТОТ КОД НЕ ВСЕГДА РАБОТАЕТ, ЧТО-ТО НЕПРАВИЛЬНО. ДЛЯ РЕШЕНИЯ ЭТОЙ ПРОБЛЕМЫ СМОТРИТЕ НА ОТВЕТ @MadPhysicist)

import numpy as np
import pandas as pd
from collections import Counter



numbers_list = [6111, 7111, 6112, 6121, 6115, 6123]

my_list = []

for number in numbers_list:
    digit_list = []
    for c in str(number):
       digit_list.append(c)
    my_list.append(digit_list)


matrix = np.array(my_list)

matrix0 = matrix

my_counter = Counter(matrix.T[0]).most_common(1)
i=0
for digit0 in matrix.T[0]:
    if digit0 != my_counter[0][0]:
        matrix0 = np.delete(matrix, i, 0)
    i += 1
matrix = matrix0

matrix1 = matrix
my_counter = Counter(matrix.T[1]).most_common(1)
i=0
for digit1 in matrix.T[1]:
    if digit1 != my_counter[0][0]:
        matrix1 = np.delete(matrix, i, 0)
    i += 1
matrix = matrix1

matrix2 = matrix
my_counter = Counter(matrix.T[2]).most_common(1)
i=0
for digit2 in matrix.T[2]:
    if digit2 != my_counter[0][0]:
        matrix2 = np.delete(matrix, i, 0)
    i += 1

matrix = matrix2

matrix3 = matrix
my_counter = Counter(matrix.T[3]).most_common(1)
i=0
for digit3 in matrix.T[3]:
    if digit3 != my_counter[0][0]:
        matrix3 = np.delete(matrix, i, 0)
    i += 1
matrix = matrix3

print (matrix[0])

1 Ответ

3 голосов
/ 08 мая 2020

Ваша идея преобразования в массив numpy - solid. Вам не нужно разделять его заранее. Серия масок и гистограмм довольно быстро сократит массив.

z = np.array([6111, 7111, 6112, 6121, 6115, 6123])

n-ые цифры (отсчитываемые от нуля) могут быть получены примерно с можно быстро выполнить с помощью np.bincount, как показано здесь :

frequentest = np.argmax(np.bincount(nth))

Вы можете выбрать элементы, которые имеют это di git на n-м месте просто

mask = nth == frequentest

Итак, теперь запустите это в al oop поверх n (в обратном направлении):

# Input array
z = np.array([6111, 7111, 6112, 6121, 6115, 6123])

# Compute the maximum number of decimal digits in the list.
# You can just manually set this to 4 if you prefer
n = int(np.ceil(np.log10(z + 1).max()))

# Empty output array
output = np.empty(n, dtype=int)

# Loop over the number of digits in reverse.
# In this case, i will be 3, 2, 1, 0.
for i in range(n - 1, -1, -1):

    # Get the ith digit from each element of z
    # The operators //, ** and % are vectorized: they operate
    # on each element of an array to return an array
    ith = (z // 10**i) % 10

    # Count the number of occurrences of each number 0-9 in the ith digit
    # Bincount returns an array of 10 elements. counts[0] is the number of 0s,
    # counts[1] is the number of 1s, ..., counts[9] is the number of 9s
    counts = np.bincount(ith)

    # argmax finds the index of the maximum element: the digit with the
    # highest count
    output[i] = np.argmax(counts)

    # Trim down the array to numbers that have the requested digit in the
    # right place. ith == output[i] is a boolean mask. It is 1 where ith
    # is the most common digit and 0 where it is not. Indexing with such a
    # mask selects the elements at locations that are non-zero.
    z = z[ith == output[i]]

Как это происходит, np.argmax вернет индекс первого максимального числа, если доступно несколько, что означает, что он всегда будет выбирать наименьшее число.

Вы можете восстановить число из output с помощью чего-то вроде

>>> output
array([1, 1, 1, 6])
>>> (output * 10**np.arange(output.size)).sum()
6111

Вы также можете просто получить оставшийся элемент z:

>>> z[0]
6111
...