python

关注公众号 jb51net

关闭
首页 > 脚本专栏 > python > Python数组的中位数

Python(Median of an Array)数组的中位数代码示例

作者:hefeng_aspnet

中位数是统计学中的一个重要概念,它表示一组数据的中间值,这篇文章主要介绍了Python数组中位数的相关资料,文中通过代码介绍的非常详细,需要的朋友可以参考下

给定一个数组arr[],任务是找到该数组的中位数。大小为 n 的数组的中位数定义为:当 n 为奇数时,中位数为中间元素;当 n 为偶数时,中位数为中间两个元素的平均值。

例如: 

输入: arr[] = [12, 3, 5, 7, 4, 19, 26]

输出: 7 

说明:给定数组 arr[] = [3, 4, 5, 7, 12, 19, 26] 的排序序列。由于元素个数为奇数,因此中位数是给定数组 arr[] 排序序列中的第 4 个元素,即 7。

输入: arr[] = [12, 3, 5, 7, 4, 26] 

输出: 6

说明:由于元素个数为偶数,中位数是给定数组 arr[] 排序后的第 3 个元素和第 4 个元素的平均值,即 (5 + 7)/2 = 6

【朴素方法】通过对数组进行排序——时间复杂度为 O(n log n),空间复杂度为 O(1)

基本思路是对数组进行排序,并检查数组大小,如果数组大小为奇数则返回中间元素,否则返回中间两个元素的平均值。

def findMedian(arr):
    n = len(arr)
    
    # First we sort the array
    arr.sort()

    # check for even case
    if n % 2 != 0:
        return arr[n // 2]

    return (arr[(n - 1) // 2] + arr[n // 2]) / 2.0

if __name__ == "__main__":
  arr = [1, 3, 4, 2, 7, 5, 8, 6]
  ans = findMedian(arr)
  print(ans)

输出

4.5

时间复杂度: O(n log n),因为我们需要先对数组进行排序。 

辅助空间: O(1)

【预期方法】:使用随机快速选择

要找到数组的中位数,可以随机选择一个基准元素,然后使用快速排序算法对数组进行分区,将较小的元素放在左侧,较大的元素放在右侧。如果基准元素落在中间索引处,则该元素即为中位数。否则,递归地对相应的子数组应用此过程。对于偶数大小的数组,可以找到中间两个元素并计算它们的平均值。

import random

def swap(arr, i, j):
    arr[i], arr[j] = arr[j], arr[i]

def partition(arr, l, r):
    lst = arr[r]
    i = l
    j = l
    while j < r:
        if arr[j] < lst:
            swap(arr, i, j)
            i += 1
        j += 1
    swap(arr, i, r)
    return i

def randomPartition(arr, l, r):
    n = r - l + 1
    pivot = random.randint(0, n - 1)
    swap(arr, l + pivot, r)
    return partition(arr, l, r)

def medianUtil(arr, l, r, k, a, b):
    if l <= r:
        partitionIndex = randomPartition(arr, l, r)
        # find the median of odd number element in arr[]
        if partitionIndex == k:
            b[0] = arr[partitionIndex]
            if a[0] != -1:
                return
        elif partitionIndex == k - 1:  # a & b as middle element of arr[]
            a[0] = arr[partitionIndex]
            if b[0] != -1:
                return
        # index in first half of the arr[]
        if partitionIndex >= k:
            medianUtil(arr, l, partitionIndex - 1, k, a, b)
            
        # find the index in second half of the arr[]
        else:
            medianUtil(arr, partitionIndex + 1, r, k, a, b)

def findMedian(arr):
    a = [-1]
    b = [-1]
    n = len(arr)
    if n % 2 == 1:
        medianUtil(arr, 0, n - 1, n // 2, a, b)
        return b[0]
    else:
        medianUtil(arr, 0, n - 1, n // 2, a, b)
        return (a[0] + b[0]) / 2.0

if __name__ == '__main__':
    arr = [12, 3, 6, 7, 4, 19]
    print(findMedian(arr))

 输出

6.5

时间复杂度: 

  1. 最佳情况分析:O(1)
  2. 平均情况分析:O(n)
  3. 最坏情况分析:O(n 2 )

辅助空间: O(n)

【最坏情况线性时间方法】——使用顺序统计量

这种新方法的思路与 quickSelect() 类似。我们通过选择一个能够平衡分割数组的枢轴点(避免一侧元素极少而另一侧元素过多),来实现最坏情况下的线性时间复杂度。数组被平衡分割后,我们采用与 quickSelect() 相同的步骤来决定从枢轴点的左侧还是右侧进行选择。有关实现细节和更多详情,请参阅“无序数组中第 K 个最小/最大元素 | 最坏情况下的线性时间复杂度” 。

注意:虽然这种方法在理论上看起来不错,但之前的快速选择方法在实践中效果更好。

总结

到此这篇关于Python数组中位数的文章就介绍到这了,更多相关Python数组的中位数内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

您可能感兴趣的文章:
阅读全文