资讯专栏INFORMATION COLUMN

pandas & matplotlib 直播数据分析

Cristalven / 470人阅读

摘要:直播数据分析针对直播间这个时间段的数据分析基础数据展示以上数据是从直播间的弹幕中提取的相关数据每个字段解释为唯一标识用户名发送的信息用户等级牌子牌子等级发言房间号依赖数据处理基础准备根据牌子名称统计最大值最小值平均值计算牌子的最大值最小值

直播数据分析

针对douyu_60937 直播间 (2018/11/19 19:04:18 - 2018/11/20 7:56:42) 这个时间段的数据分析

基础数据展示


以上数据是从直播间的弹幕中提取的相关数据,每个字段解释为

 {
    "id": "唯一标识",
    "user": "用户名",
    "cont": "发送的信息",
    "level": "用户等级",
    "sign": "牌子",
    "sign_leve": "牌子等级",
    "rid": "发言房间号",
}
依赖
pandas==0.23.4
matplotlib==3.0.2
numpy==1.15.4
datetime
数据处理 基础准备
import pandas as pd
import matplotlib.pyplot as plt
import numpy as np
import datetime

path = "douyu_60937.xlsx"
data = pd.read_excel(path)

根据牌子名称统计最大值、最小值、平均值

计算牌子的最大值、最小值、平均值的时候需要根据user 将数据删除重复项 ,避免多次计算

需要做成图我们返回值设置成dict()

t = data[["user", "sign", "sign_leve"]].drop_duplicates(subset=["user"])  # 删除重复用户
t = data.groupby("sign").sign_leve.agg(["mean", "min", "max"])
t.sort_values(["max"], ascending=False, inplace=True)
print(t)
print(t[:20].to_dict())

{"mean": {"小人参": 11.848837209302326, "196": 16.475254730713246, "女流": 11.418693982074263, "Amss": 10.0, "水煮肉": 26.0, "小僵尸": 9.93750495049505, "339": 18.941176470588236, "金发雅": 24.0, "猛男": 7.768361581920904, "小豆包": 12.676724137931034, "阿冷": 10.416666666666666, "寅子": 7.059241706161138, "小痒虫": 10.718562874251496, "S1un": 22.0, "小緑帽": 9.938271604938272, "集团军": 7.909323116219668, "小乌贼": 8.377464788732395, "点子王": 5.686131386861314, "小肚皮": 7.034911587538053, "林Q": 21.0}, "min": {"小人参": 2, "196": 4, "女流": 3, "Amss": 4, "水煮肉": 26, "小僵尸": 1, "339": 12, "金发雅": 24, "猛男": 1, "小豆包": 3, "阿冷": 6, "寅子": 1, "小痒虫": 2, "S1un": 22, "小緑帽": 1, "集团军": 1, "小乌贼": 1, "点子王": 3, "小肚皮": 1, "林Q": 21}, "max": {"小人参": 30, "196": 30, "女流": 30, "Amss": 27, "水煮肉": 26, "小僵尸": 25, "339": 25, "金发雅": 24, "猛男": 23, "小豆包": 23, "阿冷": 22, "寅子": 22, "小痒虫": 22, "S1un": 22, "小緑帽": 22, "集团军": 22, "小乌贼": 22, "点子王": 22, "小肚皮": 21, "林Q": 21}}
根据牌子名称统计数量

分类统计的时候我们要修改列名用rename(column={"老列名":"新列名"})

sign_max_count = data[["user", "sign", "sign_leve"]].drop_duplicates(subset=["user"])  # 删除重复用户
sign_max_count = data[["sign"]].groupby(["sign"]).agg({"sign": "count"}).rename(
    columns={"sign": "sign_count"})
sign_max_count.sort_values(["sign_count"], ascending=False, inplace=True)
print(sign_max_count)
print(sign_max_count[:20].to_dict())

{"sign_count": {"小肚皮": 15439, "小僵尸": 12625, "集团军": 1566, "196": 1374, "女流": 781, "影魔王": 640, "大马猴": 429, "寅子": 422, "小緑帽": 405, "小8路": 397, "小烈驴": 370, "小乌贼": 355, "小赢僧": 355, "保安团": 343, "猪芳芳": 243, "小豆包": 232, "王菠萝": 187, "二帆": 184, "猛男": 177, "汽车人": 173}}
统计各个等级的用户数量
now_data = data[["user", "level"]].drop_duplicates(subset=["user"])  # 删除重复用户
now_data = data[["level"]].groupby(["level"]).agg({"level": "count"}).rename(
    columns={"level": "level_count"})
now_data.sort_values(["level_count"], ascending=False, inplace=True)

{"level_count": {16: 3159, 19: 3122, 17: 3086, 21: 2984, 18: 2882, 15: 2832, 22: 2624, 23: 2564, 20: 2545, 13: 2379, 14: 2308, 24: 2274, 11: 2066, 12: 1894, 7: 1781, 9: 1753, 10: 1690, 8: 1678, 5: 1645, 25: 1554}}
每小时发言数量

根据时间统计需要构造一个datetime 数据类型的列 , 利用 resample("时间标识符") + count() 进行统计

为了后续制图方便我在这里直接把 转换成python 内置的 datetime 类 方法是 to_pydatetime

df = data
df = df.loc[:, ("cont", "uptime")]
df = df.set_index("uptime")
result = df.resample("H").count().rename(columns={"cont": "user_count"})
print(result)
result = result.to_dict()

s = {}
for k, v in result["user_count"].items():
    s[k.to_pydatetime()] = v
result["user_count"] = s

print(result)
return result

{"user_count": {datetime.datetime(2018, 11, 19, 19, 0): 12707, datetime.datetime(2018, 11, 19, 20, 0): 12374, datetime.datetime(2018, 11, 19, 21, 0): 19340, datetime.datetime(2018, 11, 19, 22, 0): 13530, datetime.datetime(2018, 11, 19, 23, 0): 8, datetime.datetime(2018, 11, 20, 0, 0): 2, datetime.datetime(2018, 11, 20, 1, 0): 1, datetime.datetime(2018, 11, 20, 2, 0): 0, datetime.datetime(2018, 11, 20, 3, 0): 0, datetime.datetime(2018, 11, 20, 4, 0): 5, datetime.datetime(2018, 11, 20, 5, 0): 1, datetime.datetime(2018, 11, 20, 6, 0): 11, datetime.datetime(2018, 11, 20, 7, 0): 23}}
每小时在线人数(发言人)
df = data.drop_duplicates(subset=["user"])
df = df.loc[:, ("user", "uptime")]
df = df.set_index("uptime")
result = df.resample("H").count().rename(columns={"user": "user_count"})
print(result)
result = result.to_dict()
s = {}
for k, v in result["user_count"].items():
    s[k.to_pydatetime()] = v
result["user_count"] = s
print(result)

{"user_count": {datetime.datetime(2018, 11, 19, 19, 0): 4223, datetime.datetime(2018, 11, 19, 20, 0): 2207, datetime.datetime(2018, 11, 19, 21, 0): 3843, datetime.datetime(2018, 11, 19, 22, 0): 1875, datetime.datetime(2018, 11, 19, 23, 0): 6, datetime.datetime(2018, 11, 20, 0, 0): 0, datetime.datetime(2018, 11, 20, 1, 0): 1, datetime.datetime(2018, 11, 20, 2, 0): 0, datetime.datetime(2018, 11, 20, 3, 0): 0, datetime.datetime(2018, 11, 20, 4, 0): 1, datetime.datetime(2018, 11, 20, 5, 0): 1, datetime.datetime(2018, 11, 20, 6, 0): 1, datetime.datetime(2018, 11, 20, 7, 0): 4}}
制作图表 粉丝牌等级情况 柱状图
def autolabel(ax, rects, xpos="center"):
    xpos = xpos.lower()
    ha = {"center": "center", "right": "left", "left": "right"}
    offset = {"center": 0.5, "right": 0.57, "left": 0.43}

    for rect in rects:
        height = rect.get_height()
        ax.text(rect.get_x() + rect.get_width() * offset[xpos], 1.01 * height,
                "{}".format(height), ha=ha[xpos], va="bottom")


def sign_bar_wiht_leve(t1):
    """
    粉丝牌等级情况柱状图
    :return:
    """
    mean = [round(x, 1) for x in t1["mean"].values()]
    min = t1["min"].values()
    max = t1["max"].values()
    ind = np.arange(len(mean))
    width = 0.35
    fig, ax = plt.subplots()
    rects_2 = ax.bar(ind, min, width / 2, color="IndianRed", label="最低等级")
    rects_1 = ax.bar(ind + width / 2, mean, width / 2, color="SkyBlue", label="平均等级")
    rects_3 = ax.bar(ind + width, max, width / 2, color="Black", label="最高等级")
    ax.set_ylabel("等级")
    ax.set_title("粉丝牌等级 (2018/11/19  19:04:18 - 2018/11/20  7:56:42)")
    ax.set_xticks(ind)
    ax.set_xticklabels(t1["mean"].keys())
    ax.legend()
    fig = plt.gcf()
    fig.set_size_inches(30, 10.5)
    autolabel(ax=ax, rects=rects_1, xpos="center")
    autolabel(ax=ax, rects=rects_2, xpos="center")
    autolabel(ax=ax, rects=rects_3, xpos="center")
    fig.savefig("粉丝牌等级.jpg")
    fig.show()

粉丝牌占比 饼图
def sign_pie_with_count(t2):
    """
    粉丝牌占比
    :param t2:
    :return:
    """
    sizes = list(t2["sign_count"].values())[:5]
    labels = list(t2["sign_count"].keys())[:5]
    plt.figure(figsize=(8, 4))  # 调节图形大小
    explode = (0, 0, 0, 0)  # 将某一块分割出来,值越大分割出的间隙越大
    patches, text1, text2 = plt.pie(sizes,
                                    labels=labels,
                                    autopct="%3.2f%%",  # 数值保留固定小数位
                                    shadow=False,  # 无阴影设置
                                    startangle=90,  # 逆时针起始角度设置
                                    pctdistance=0.8)  # 数值距圆心半径倍数距离
    plt.axis("equal")
    plt.legend()
    plt.title("粉丝牌占比 
(2018/11/19  19:04:18 - 2018/11/20  7:56:42)")
    plt.savefig("粉丝牌占比.jpg")
    plt.show()

用户等级分布 折线图
def user_line_with_count(t4):
    """
    用户等级分布折线图
    :param t4:
    :return:
    """
    t4 = sorted(t4["level_count"].items(), key=lambda d: d[0])

    x = [i[0] for i in t4]
    y = [i[1] for i in t4]

    plt.figure(figsize=(8, 4))
    plt.plot(x, y, "b--", linewidth=1)

    # 设置数字标签
    for a, b in zip(x, y):
        plt.text(a, b, b, ha="center", va="bottom", fontsize=10)

    plt.xlabel("用户等级")
    plt.ylabel("数量")
    plt.title("用户等级情况
(2018/11/19  19:04:18 - 2018/11/20  7:56:42)")
    plt.savefig("用户等级情况.jpg")
    plt.show()

每个时间段用户以及弹幕量 折线图
def show_label(x, y, plt):
    # 设置数字标签
    for a, b in zip(x, y):
        plt.text(a, b, b, ha="center", va="bottom", fontsize=10)


def user_time(t5, t6):
    """
    每个时间段用户以及弹幕量
    :param t5:
    :param t6:
    :return:
    """
    t_5 = {k.strftime("%Y-%m-%d %H"): v for k, v in t5["user_count"].items()}
    t_6 = {k.strftime("%Y-%m-%d %H"): v for k, v in t6["user_count"].items()}

    x_1 = t_5.keys()
    y_1 = t_5.values()

    x_2 = t_6.keys()
    y_2 = t_6.values()

    plt.figure(figsize=(9, 5))
    plt.plot(x_1, y_1, "o-", linewidth=1, label="弹幕数量")
    plt.plot(x_2, y_2, "g--", linewidth=1, label="在线人数")
    show_label(x_1, y_1, plt)
    show_label(x_2, y_2, plt)
    plt.xticks(rotation=30)
    plt.legend()

    plt.xlabel("小时")
    plt.ylabel("人数")
    plt.title("每个时间段用户以及弹幕量
(2018/11/19  19:04:18 - 2018/11/20  7:56:42)")
    plt.savefig("每个时间段用户以及弹幕量.jpg")
    plt.show()

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/42636.html

相关文章

  • Python如何利用pandas读取csv数据并绘图

      小编写这篇文章的一个主要目的,主要是给大家去做一个解答,解答的内容主要是Python相关知识,比如说,会给大家讲解怎么样去利用Python pandas去做一个读取,读取的是csv数据,然后将这些数据去做一个绘图处理,具体内容下面给大家详细解答。  如何利用pandas读取csv数据并绘图  导包,常用的numpy和pandas,绘图模块matplotlib,  importmatplotli...

    89542767 评论0 收藏0
  • PandasMatplotlib保存图型时纵坐标标识过长造成显示不全问题解决

      在使用matplotlib做图得时候,有时候会碰到绘图时显示不全和图片保存时不完美的难题,本文主要是为大家介绍了有关PandasMatplotlib保存图型时纵坐标标识过长造成显示不全问题解决方式,需用的小伙伴可以参考一下。  序言  这篇blog主要是处理在使用pandas制作图象并储存时,因为标识过长,造成纵坐标上标签显示不全问题。刚遇到困难的时候修改了一下下图片尺寸,然而并没有卵用,因此...

    89542767 评论0 收藏0
  • python数学建模Numpy应用介绍与Pandas学习

      小编写这篇文章的主要目的,主要是来给大家解答下关于python数学建模的一些相关的介绍,涉及到内容涵盖Numpy的一些相关的应用具体的一些介绍。另外,还会涉及到相关的Pandas学习知识,具体内容下面给大家详细解答下。  1 Numpy介绍与应用  1-1Numpy是什么  NumPy是一个运行速度非常快的数学库,一个开源的的python科学计算库,主要用于数组、矩阵计算,包含:  一个强大的...

    89542767 评论0 收藏0
  • Python绘制数据动态图的方法详解

      小编写这篇文章的一个主要目的,主要是给大家去做一个介绍,介绍的内容是,利用Python这门语言,去绘制相关的数据动态图表,那么,具体的绘制方法是什么呢?下面小编就给大家详细的解答。  数据动态图怎么做,效果图,  多子图联动竞赛图  安装  pipinstallpandas_alive   #或者   condainstallpandas_alive-cconda-forge   玩起来  支...

    89542767 评论0 收藏0
  • python数学建模之Numpy应用介绍与Pandas学习

      小编写这篇文章的一个主要目的,主要是来给大家去做一个介绍。介绍的内容主要是关于建模知识的一些相关介绍,包括其Pandas的一些相关学习,就具体的操作内容,下面就给大家详细解答下。  Numpy学习  1 Numpy介绍与应用  1-1Numpy是什么  NumPy是一个运行速度非常快的数学库,一个开源的的python科学计算库,主要用于数组、矩阵计算,包含:  一个强大的N维数组对象ndarr...

    89542767 评论0 收藏0

发表评论

0条评论

最新活动
阅读需要支付1元查看
<