如何根据中位数将列表拆分为 2 个未排序的分组
How to split a list into 2 unsorted groupings based on the median
我的目标是将列表分类为不需要分类的两个小节。
假设我有一个长度为 10 的列表,其中包含值 0-9。
arr = [50, 30, 20, 10, 90, 40, 100, 70, 60, 80]
我希望以索引 0 到 4 包含值 10、20、30、40 和 50 的任何顺序的方式对其进行排序。
例如:
# SPLIT HERE V
[40, 30, 20, 50, 10, 70, 60, 80, 90, 100]
我研究了各种分而治之的排序算法,但我不确定在这种情况下使用哪种算法最好。
我目前的想法是使用快速排序,但我相信有更好的方法来完成我正在寻找的事情,因为不需要对所有内容进行精确排序,而是在所有值的“一般”意义上进行排序在任何顺序中都位于中位数的各自一侧。
statistics
程序包有一种方法可以计算一列数字的中位数。从那里,您可以使用 for
循环根据值是否大于中位数将值分成两个单独的列表:
from statistics import median
arr = [50, 30, 20, 10, 90, 40, 100, 70, 60, 80]
med = median(arr)
result1 = []
result2 = []
for item in arr:
if item <= med:
result1.append(item)
else:
result2.append(item)
print(result1)
print(result2)
这输出:
[50, 30, 20, 10, 40]
[90, 100, 70, 60, 80]
您可以使用 numpy 执行此操作(如果 arr 很大,它会明显更快):
import numpy as np
arr = [50, 30, 20, 10, 90, 40, 100, 70, 60, 80]
arr = np.array(arr)
median = np.median(arr)
result1 = arr[arr <= median]
result2 = arr[arr > median]
输出:
array([50, 30, 20, 10, 40])
array([ 90, 100, 70, 60, 80])
如果你想要一个列表作为输出,你可以这样做:
[*result1, *result2]
输出:
[50, 30, 20, 10, 40, 90, 100, 70, 60, 80]
如果您想从头开始解决问题,您可以实现 Median of Medians algorithm 以在线性时间内找到未排序数组的中位数。那要看你的目标是什么了。
如果您想就地重新排序,您可以使用中位数中位数算法的结果 select 分区算法的枢轴(快速排序的一部分)。
另一方面,使用 python 您可以遍历数组并将值分别附加到左侧或右侧数组。
其他当前的其他答案将列表分成两个列表,根据您的示例,我的印象是有两个分组,但输出是一个列表。
import numpy as np
# setup
arr = [50, 30, 20, 10, 90, 40, 100, 70, 60, 80]
# output array
unsorted_grouping = []
# get median
median = np.median(arr)
# loop over array, if greater than median, append. Append always assigns
# values at the end of array
# else insert it at position 0, the beginning / left side
for val in arr:
if val >= median:
unsorted_grouping.append(val)
else:
unsorted_grouping.insert(0, val)
# output
unsorted_grouping
[40, 10, 20, 30, 50, 90, 100, 70, 60, 80]
您可以使用 statistics
模块计算中位数,然后使用它将每个值添加到一组或另一组:
import statistics
arr = [50, 30, 20, 10, 90, 40, 100, 70, 60, 80]
median = statistics.median(arr)
bins = [], [] # smaller and bigger values
for value in arr:
bins[value > median].append(value)
print(bins[0]) # -> [50, 30, 20, 10, 40]
print(bins[1]) # -> [90, 100, 70, 60, 80]
对我来说,这似乎可以解决问题,除非您确实需要无序输出:
arr = [50, 30, 20, 10, 90, 40, 100, 70, 60, 80]
sorted_arr = sorted(arr)
median_index = len(arr)//2
sub_list1, sub_list2 = sorted_arr[:median_index],sorted_arr[median_index:]
这输出:
[10, 20, 30, 40, 50] [60, 70, 80, 90, 100]
我的第一个Python节目,还请多多包涵。
基本上按照您的建议进行快速排序,但仅 sub-sorts 包含中值索引的分区。
arr = [50, 30, 20, 10, 90, 40, 100, 70, 60, 80]
def partition(a, left, right):
pivot = (left + right)//2
a[left],a[pivot] = a[pivot], a[left] # swap
pivot = left
left += 1
while right >= left :
while left <= right and a[left] <= a[pivot] :
left += 1
while left <= right and a[right] > a[pivot] :
right -= 1
if left <= right:
a[left] , a[right] = a[right], a[left]
left += 1
right -= 1
else:
break
a[pivot], a[right] = a[right] , a[pivot]
return right
def medianSplit(array):
left = 0;
right = len(array) - 1;
med = len(array) // 2;
while (left < right):
pivot = partition(array, left, right)
if pivot > med:
right = pivot - 1;
else:
left = pivot + 1;
def main():
medianSplit(arr)
print(arr)
main()
我的目标是将列表分类为不需要分类的两个小节。
假设我有一个长度为 10 的列表,其中包含值 0-9。
arr = [50, 30, 20, 10, 90, 40, 100, 70, 60, 80]
我希望以索引 0 到 4 包含值 10、20、30、40 和 50 的任何顺序的方式对其进行排序。
例如:
# SPLIT HERE V
[40, 30, 20, 50, 10, 70, 60, 80, 90, 100]
我研究了各种分而治之的排序算法,但我不确定在这种情况下使用哪种算法最好。
我目前的想法是使用快速排序,但我相信有更好的方法来完成我正在寻找的事情,因为不需要对所有内容进行精确排序,而是在所有值的“一般”意义上进行排序在任何顺序中都位于中位数的各自一侧。
statistics
程序包有一种方法可以计算一列数字的中位数。从那里,您可以使用 for
循环根据值是否大于中位数将值分成两个单独的列表:
from statistics import median
arr = [50, 30, 20, 10, 90, 40, 100, 70, 60, 80]
med = median(arr)
result1 = []
result2 = []
for item in arr:
if item <= med:
result1.append(item)
else:
result2.append(item)
print(result1)
print(result2)
这输出:
[50, 30, 20, 10, 40]
[90, 100, 70, 60, 80]
您可以使用 numpy 执行此操作(如果 arr 很大,它会明显更快):
import numpy as np
arr = [50, 30, 20, 10, 90, 40, 100, 70, 60, 80]
arr = np.array(arr)
median = np.median(arr)
result1 = arr[arr <= median]
result2 = arr[arr > median]
输出:
array([50, 30, 20, 10, 40])
array([ 90, 100, 70, 60, 80])
如果你想要一个列表作为输出,你可以这样做:
[*result1, *result2]
输出:
[50, 30, 20, 10, 40, 90, 100, 70, 60, 80]
如果您想从头开始解决问题,您可以实现 Median of Medians algorithm 以在线性时间内找到未排序数组的中位数。那要看你的目标是什么了。
如果您想就地重新排序,您可以使用中位数中位数算法的结果 select 分区算法的枢轴(快速排序的一部分)。
另一方面,使用 python 您可以遍历数组并将值分别附加到左侧或右侧数组。
其他当前的其他答案将列表分成两个列表,根据您的示例,我的印象是有两个分组,但输出是一个列表。
import numpy as np
# setup
arr = [50, 30, 20, 10, 90, 40, 100, 70, 60, 80]
# output array
unsorted_grouping = []
# get median
median = np.median(arr)
# loop over array, if greater than median, append. Append always assigns
# values at the end of array
# else insert it at position 0, the beginning / left side
for val in arr:
if val >= median:
unsorted_grouping.append(val)
else:
unsorted_grouping.insert(0, val)
# output
unsorted_grouping
[40, 10, 20, 30, 50, 90, 100, 70, 60, 80]
您可以使用 statistics
模块计算中位数,然后使用它将每个值添加到一组或另一组:
import statistics
arr = [50, 30, 20, 10, 90, 40, 100, 70, 60, 80]
median = statistics.median(arr)
bins = [], [] # smaller and bigger values
for value in arr:
bins[value > median].append(value)
print(bins[0]) # -> [50, 30, 20, 10, 40]
print(bins[1]) # -> [90, 100, 70, 60, 80]
对我来说,这似乎可以解决问题,除非您确实需要无序输出:
arr = [50, 30, 20, 10, 90, 40, 100, 70, 60, 80]
sorted_arr = sorted(arr)
median_index = len(arr)//2
sub_list1, sub_list2 = sorted_arr[:median_index],sorted_arr[median_index:]
这输出:
[10, 20, 30, 40, 50] [60, 70, 80, 90, 100]
我的第一个Python节目,还请多多包涵。
基本上按照您的建议进行快速排序,但仅 sub-sorts 包含中值索引的分区。
arr = [50, 30, 20, 10, 90, 40, 100, 70, 60, 80]
def partition(a, left, right):
pivot = (left + right)//2
a[left],a[pivot] = a[pivot], a[left] # swap
pivot = left
left += 1
while right >= left :
while left <= right and a[left] <= a[pivot] :
left += 1
while left <= right and a[right] > a[pivot] :
right -= 1
if left <= right:
a[left] , a[right] = a[right], a[left]
left += 1
right -= 1
else:
break
a[pivot], a[right] = a[right] , a[pivot]
return right
def medianSplit(array):
left = 0;
right = len(array) - 1;
med = len(array) // 2;
while (left < right):
pivot = partition(array, left, right)
if pivot > med:
right = pivot - 1;
else:
left = pivot + 1;
def main():
medianSplit(arr)
print(arr)
main()