如何从 4 位数字列表中找到最频繁的累进数字
How to find the most frequent progressive digit from a list of 4-digits numbers
我在 Python 编程方面还很陌生。从 4 位数字列表中找到最频繁的渐进数字的有效和 Pyhtonic 方法是什么?
假设我有以下列表:[6111, 7111, 6112, 6121, 6115, 6123]
。
逻辑是观察第一个数字 6 出现频率最高。为了接下来的考虑,我可以删除数字 7111。
对于第二个数字,我考虑了新的候选 [6111, 6112, 6121, 6115, 6123]
,我观察到 1 是最常见的数字,依此类推。
在算法结束时,我将只剩下 1 个列表。
如果有 2 个或更多数字出现相同的数字,我可以在所有数字中随机选择较小的一个。
一种简单的方法是将列表转换为 Nx4 矩阵,并为每一列考虑最频繁的数字。这可能行得通,但我发现解决这个问题的方法非常愚蠢且效率低下。有人可以帮忙吗?
编辑:我的这个解决方案的代码(注意:这个代码并不总是有效,有些地方是错误的。这个问题的解决方案请参考@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])
您转换为 numpy 数组的想法是可靠的。您不需要预先拆分它。一系列掩码和直方图将相当快地减少阵列。
z = np.array([6111, 7111, 6112, 6121, 6115, 6123])
第 n 位数字(从零开始)可以通过类似
的方式获得
nth = (z // 10**n) % 10
使用 np.bincount
as shown here:
可以快速完成最频繁的计数
frequentest = np.argmax(np.bincount(nth))
您可以 select 具有第 n 个数字的元素
mask = nth == frequentest
所以现在 运行 这在 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
将 return 第一个最大计数的索引,这意味着它将始终 select 最小的数字。
您可以使用
之类的东西从 output
恢复号码
>>> output
array([1, 1, 1, 6])
>>> (output * 10**np.arange(output.size)).sum()
6111
你也可以只得到z
的剩余元素:
>>> z[0]
6111
我在 Python 编程方面还很陌生。从 4 位数字列表中找到最频繁的渐进数字的有效和 Pyhtonic 方法是什么?
假设我有以下列表:[6111, 7111, 6112, 6121, 6115, 6123]
。
逻辑是观察第一个数字 6 出现频率最高。为了接下来的考虑,我可以删除数字 7111。
对于第二个数字,我考虑了新的候选 [6111, 6112, 6121, 6115, 6123]
,我观察到 1 是最常见的数字,依此类推。
在算法结束时,我将只剩下 1 个列表。
如果有 2 个或更多数字出现相同的数字,我可以在所有数字中随机选择较小的一个。
一种简单的方法是将列表转换为 Nx4 矩阵,并为每一列考虑最频繁的数字。这可能行得通,但我发现解决这个问题的方法非常愚蠢且效率低下。有人可以帮忙吗?
编辑:我的这个解决方案的代码(注意:这个代码并不总是有效,有些地方是错误的。这个问题的解决方案请参考@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])
您转换为 numpy 数组的想法是可靠的。您不需要预先拆分它。一系列掩码和直方图将相当快地减少阵列。
z = np.array([6111, 7111, 6112, 6121, 6115, 6123])
第 n 位数字(从零开始)可以通过类似
的方式获得nth = (z // 10**n) % 10
使用 np.bincount
as shown here:
frequentest = np.argmax(np.bincount(nth))
您可以 select 具有第 n 个数字的元素
mask = nth == frequentest
所以现在 运行 这在 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
将 return 第一个最大计数的索引,这意味着它将始终 select 最小的数字。
您可以使用
之类的东西从output
恢复号码
>>> output
array([1, 1, 1, 6])
>>> (output * 10**np.arange(output.size)).sum()
6111
你也可以只得到z
的剩余元素:
>>> z[0]
6111