直方图与计数:`np.histogram`, `np.bincount`

好的,各位观众老爷,欢迎来到今天的“数据挖掘之奇技淫巧”讲堂!今天我们要聊的是数据分析界两位低调但实力爆表的英雄:np.histogramnp.bincount

别看它们名字平平无奇,就像隔壁老王一样,但它们的功能却相当犀利,能帮你快速统计数据分布,绘制精美的直方图,简直是数据可视化的好帮手!😎

第一幕:np.histogram——直方图大师的华丽登场

想象一下,你手里有一大堆数据,比如全班同学的考试成绩、网站用户的年龄、某个股票的价格波动等等。你想快速了解这些数据的分布情况,看看哪些分数段的人最多,哪些年龄段的用户最活跃,股票价格主要集中在哪个区间。这时候,np.histogram 就能闪亮登场,帮你把数据变成一幅直观的直方图!

什么是直方图呢?简单来说,就是把数据分成若干个“桶”(bins),然后统计每个桶里有多少个数据,最后用柱状图的形式展示出来。柱子越高,说明这个桶里的数据越多。

np.histogram 的基本用法非常简单:

import numpy as np
import matplotlib.pyplot as plt

# 模拟一些数据,比如1000个随机数,服从正态分布
data = np.random.normal(0, 1, 1000)

# 使用 np.histogram 计算直方图
counts, bin_edges = np.histogram(data, bins=10)

# counts: 每个bin里的数据数量
# bin_edges: 每个bin的边界值

print("每个bin的数据数量:", counts)
print("每个bin的边界值:", bin_edges)

# 使用 matplotlib 绘制直方图
plt.hist(data, bins=10)
plt.xlabel("数据值")
plt.ylabel("频数")
plt.title("直方图示例")
plt.show()

这段代码做了什么呢?

  1. 生成数据: 我们用 np.random.normal 生成了1000个服从正态分布的随机数,模拟一些真实的数据。
  2. 计算直方图: np.histogram(data, bins=10) 是核心部分。它把数据 data 分成10个桶(bins=10),然后统计每个桶里有多少个数据。返回值 counts 是一个数组,表示每个桶里的数据数量;bin_edges 也是一个数组,表示每个桶的边界值。
  3. 绘制直方图: 我们用 matplotlib.pyplot.hist 函数把直方图画出来。这个函数可以直接使用 np.histogram 的结果,也可以直接传入数据和桶的数量。

np.histogram 的参数详解

np.histogram 函数有很多参数,可以让你灵活地控制直方图的生成方式。我们来详细了解一下:

  • a 必须参数,输入的数据,可以是数组或列表。
  • bins 指定桶的数量或桶的边界值。它可以是整数,表示桶的数量;也可以是数组,表示每个桶的边界值。例如,bins=20 表示分成20个等宽的桶,bins=[0, 1, 2, 3, 4, 5] 表示桶的边界值为0, 1, 2, 3, 4, 5。
  • range 指定数据的范围。如果指定了 range,那么只有在这个范围内的数据才会被统计到直方图中。例如,range=(0, 10) 表示只统计0到10之间的数据。
  • density 如果设置为 True,那么直方图的高度将被归一化,表示概率密度。也就是说,直方图的面积将等于1。
  • weights 可以为每个数据点指定权重。如果指定了 weights,那么在统计直方图时,每个数据点都会被乘以它的权重。例如,如果你想统计不同年龄段的用户在网站上的活跃度,你可以把每个用户的权重设置为他们在网站上的停留时间。
  • normed (Deprecated, use density instead)
  • cumulative 如果设置为 True,那么直方图将显示累积分布。也就是说,每个桶的高度表示小于等于这个桶边界值的数据的数量。
  • bottom 可以为直方图指定一个基线。
  • histtype 指定直方图的类型。可以是 'bar' (默认), 'barstacked', 'step', 或 'stepfilled'
  • align 指定柱子的对齐方式。可以是 'left', 'mid', 或 'right'
  • orientation 指定直方图的方向。可以是 'vertical' (默认) 或 'horizontal'
  • rwidth 指定柱子的宽度相对于桶的宽度的比例。
  • log 如果设置为 True,那么直方图的y轴将使用对数刻度。
  • color 指定柱子的颜色。
  • label 为直方图指定标签。
  • stacked 如果设置为 True,那么多个直方图将被堆叠在一起。

举个栗子:加权直方图

假设你是一家电商公司的数据分析师,你想分析不同年龄段的用户在网站上的消费金额。你可以使用加权直方图来实现这个目标:

import numpy as np
import matplotlib.pyplot as plt

# 模拟一些数据
ages = np.random.randint(18, 65, 1000)  # 用户年龄
spendings = np.random.normal(100, 50, 1000)  # 用户消费金额

# 使用 np.histogram 计算加权直方图
counts, bin_edges = np.histogram(ages, bins=10, weights=spendings)

# counts: 每个bin里的总消费金额
# bin_edges: 每个bin的边界值

print("每个年龄段的总消费金额:", counts)
print("每个年龄段的边界值:", bin_edges)

# 使用 matplotlib 绘制直方图
plt.bar(bin_edges[:-1], counts, width=(bin_edges[1] - bin_edges[0]))
plt.xlabel("年龄")
plt.ylabel("总消费金额")
plt.title("不同年龄段用户的消费金额")
plt.show()

在这个例子中,我们把用户的年龄作为数据,把用户的消费金额作为权重。np.histogram 会统计每个年龄段的总消费金额,然后我们用柱状图把结果展示出来。

第二幕:np.bincount——小而美的计数器

np.bincount 是一个更加简单但非常实用的函数,它的作用是统计非负整数数组中每个值出现的次数。它就像一个高效的计数器,可以快速地统计数据中每个值的频率。

np.bincount 的基本用法如下:

import numpy as np

# 模拟一些数据,比如一个包含 0 到 9 的随机整数数组
data = np.random.randint(0, 10, 20)

# 使用 np.bincount 统计每个值出现的次数
counts = np.bincount(data)

# counts: 一个数组,counts[i] 表示值 i 出现的次数

print("每个值出现的次数:", counts)

这段代码做了什么呢?

  1. 生成数据: 我们用 np.random.randint 生成了一个包含0到9的随机整数数组。
  2. 统计频率: np.bincount(data) 会统计数组 data 中每个值出现的次数。返回值 counts 是一个数组,counts[i] 表示值 i 出现的次数。

np.bincount 的参数详解

np.bincount 函数的参数比较简单:

  • x 必须参数,输入的数据,必须是非负整数数组。
  • weights 可以为每个数据点指定权重。如果指定了 weights,那么在统计频率时,每个数据点都会被乘以它的权重。
  • minlength: 如果指定了 minlength,那么返回的数组的长度至少为 minlength。 如果 minlength 大于输入数组中最大值,则在数组末尾补0,保证数组长度为 minlength

举个栗子:带权重的计数

假设你是一家游戏公司的运营,你想统计不同等级的玩家在游戏中的活跃度。你可以使用带权重的 np.bincount 来实现这个目标:

import numpy as np

# 模拟一些数据
levels = np.random.randint(1, 101, 1000)  # 玩家等级,假设等级范围是1到100
online_times = np.random.normal(60, 30, 1000)  # 玩家在线时长,单位分钟

# 使用 np.bincount 统计每个等级的玩家总在线时长
total_online_times = np.bincount(levels, weights=online_times)

# total_online_times: 一个数组,total_online_times[i] 表示等级为 i 的玩家的总在线时长

print("每个等级的玩家总在线时长:", total_online_times)

在这个例子中,我们把玩家的等级作为数据,把玩家的在线时长作为权重。np.bincount 会统计每个等级的玩家的总在线时长,这样你就可以知道哪个等级的玩家最活跃了。

第三幕:np.histogram vs np.bincount——谁更胜一筹?

np.histogramnp.bincount 都是用于统计数据分布的函数,但它们的应用场景有所不同。

  • np.histogram 适用于统计连续数据的分布,可以灵活地指定桶的数量和边界值,还可以进行归一化、加权等操作。
  • np.bincount 适用于统计非负整数数组中每个值出现的次数,速度非常快,但只能处理非负整数数据。

可以用一个表格来总结它们的区别:

特性 np.histogram np.bincount
数据类型 连续数据 非负整数
桶的定义 可以自定义桶的数量和边界值 隐式定义,每个整数值对应一个桶
功能 统计数据在不同桶中的分布,可绘制直方图 统计每个整数值出现的次数
速度 相对较慢 非常快
适用场景 数据分布分析、直方图绘制 统计频率、计数
是否可加权 可以 可以

总结:

np.histogramnp.bincount 都是数据分析工具箱中不可或缺的利器。np.histogram 擅长处理连续数据,绘制直方图,让你一目了然地了解数据的分布情况;np.bincount 则擅长处理非负整数数据,快速统计每个值的频率,帮你高效地进行计数。

在实际应用中,你需要根据数据的类型和分析目标选择合适的函数。如果你的数据是连续的,或者你需要绘制直方图,那么 np.histogram 是你的首选;如果你的数据是非负整数,并且你需要快速统计每个值的频率,那么 np.bincount 绝对不会让你失望。

掌握了这两个函数,你就可以更加轻松地驾驭数据,挖掘数据背后的价值,成为真正的数据分析大师!🎉

最后,希望今天的讲堂对你有所帮助。记住,数据分析不是枯燥的数字游戏,而是一场充满乐趣的探险。拿起你的工具,开始你的数据挖掘之旅吧!🚀

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注