[利用python进行数据分析01] “来⾃Bitly的USA.gov数据” 分析出各个地区的 windows和非windows用户

2011 年, URL 缩短服务 Bitly 跟美国政府⽹站 USA.gov 合作,提供
了⼀份从⽣成 .gov .mil 短链接的⽤户那⾥收集来的匿名数据。
2011 年,除实时数据之外,还可以下载⽂本⽂件形式的每⼩时
快照。
数据集下载:通过百度网盘分享的文件:example.txt
链接:https://pan.baidu.com/s/1t4AzSwytJOG0ZYNMjx7FtQ?pwd=w2ia 
提取码:w2ia 
--来自百度网盘超级会员V6的分享
设置一下库的依赖

from numpy.random import randn
import numpy as np
np.random.seed(123)
import os
import matplotlib.pyplot as plt
import pandas as pd
plt.rc("figure", figsize=(10, 6))
np.set_printoptions(precision=4)
pd.options.display.max_columns = 20
pd.options.display.max_rows = 20
pd.options.display.max_colwidth = 80


首先我们先读取下数据集
import json# 使用 'utf-8' 编码打开文件,避免 UnicodeDecodeError
with open(path, encoding='utf-8') as f:records = [json.loads(line) for line in f]
print(records)


 

Python 有内置或第三⽅模块可以将 JSON 字符串转换成 Python
典对象。这⾥,我将使⽤ json 模块及其 loads 函数逐⾏加载已经下
载好的数据⽂件。现在, records 对象就成为⼀组 Python 字典了
直接我们使用.get()方法获取'c'键默认返回Node如果键不存在
time_zones=[rec.get("tz") for rec in records]




然后我们写一个统计数量的函数
写法1:
def get_counts(sequence):counts={}for x in sequence:if x in counts:counts[x]+=1else:counts[x]=1return counts

然后我们就可以统计“c”数列下“US”的个数:
 

counts = get_counts(country_zones)
print(counts["US"])
len(country_zones)


方法2:
defaultdict,这是 collections 模块中的一种字典类型,可以指定默认的工厂函数,用于在访问不存在的键时自动初始化键的值。
 

counts = defaultdict(int):

  • 创建一个 defaultdict 对象 counts,并指定 int 作为默认值的工厂函数。
  • int() 返回 0,所以每当一个新的键被访问时,默认值就是 0
  • 例如,如果访问一个键 "key1",而 "key1" 不存在,则 counts["key1"] 会自动初始化为 0
     
  • for x in sequence::

    • 遍历传入的 sequence(可以是列表、字符串等任意可迭代对象),xsequence 中的每个元素。
  • counts[x] += 1:

    • 对每个元素 x,将其作为键在 counts 中进行累加。
    • 如果 x 已经在 counts 中,则增加其对应的值(计数)。
    • 如果 x 不在 counts 中,则 defaultdict 自动初始化为 0,然后执行 += 1,计数变为 1
  • return counts:

    • 返回包含元素计数的 defaultdict

       
      from collections import defaultdictdef get_counts2(sequence):counts = defaultdict(int) # values will initialize to 0for x in sequence:counts[x] += 1return counts



      我们还能写一个函数来统计最大的几个数量,从小到大排序

    • 方法1:
       

      def top_counts(count_dict, n=10):value_key_pairs = [(count, tz) for tz, count in count_dict.items()]value_key_pairs.sort()return value_key_pairs[-n:]


      方法2:
      直接调用collections 下的 Counter模块返回最大的10个

      from collections import Counter
      counts = Counter(country_zones)
      counts.most_common(10)



      之后我们打算用pandas对这个数据集进行分析我们使用DataFrame

      frame = pd.DataFrame(records)
      print(frame.info())
      print(frame["tz"])
      frame["tz"].head()



      从DataFrame里面提取出来c列
       

      tz_counts = frame["c"].value_counts()
      tz_counts.head()
      tz_counts[:10]



      我们对缺失的c列进行填充
      主要目的是对 frame 数据框中的 "c" 列进行清洗,将缺失值替换为 "Missing",将空字符串替换为 "Unknown",然后统计每个时区(c)的出现次数。
       

      clean_c=frame["c"].fillna("Missing")
      print(clean_c)
      clean_c[clean_c == ""] = "Unknown"
      c_counts = clean_c.value_counts()
      c_counts.head()



      然后我们调用seaborn库对统计的次数进行绘图

      import seaborn as sns
      subset = c_counts.head()
      sns.barplot(y=subset.index, x=subset.to_numpy())





      然后我们对数据集的a标签进行分析
      给整个dataframe加一个os列



       

      frame["a"].dropna():

    • frame 数据框中提取 "a" 列,并使用 .dropna() 方法移除所有的缺失值(NaN)。这确保后续操作不会因空值引发错误。
       

      [x.split()[0] for x in frame["a"].dropna()]:

    • 这是一个列表推导式,用于处理 "a" 列中的每个非空字符串 x
    • x.split():将字符串 x 按照空格拆分为一个列表,包含各个单词。
    • x.split()[0]:获取拆分后的第一个单词,即列表中的第一个元素。
    • 这一过程将 "a" 列中每个字符串的第一个单词提取出来。
    • pd.Series([...]):

      • 将提取出的第一个单词列表转换为一个 Pandas Series 对象,方便后续的统计和分析。
    • print(results.head(5)):

      • 打印 results Series 的前 5 个元素,查看提取出的第一个单词。
    • results.value_counts():

      • value_counts() 方法统计 results 中每个唯一值的出现次数,并按频次降序排列。
      • 返回的结果是一个 Series,其中索引是唯一值,值是对应的出现次数。
    • print(results.value_counts().head(8)):

      • 打印前 8 个最常见的第一个单词及其出现次数,便于查看数据分布情况

    •  
    • frame["a"].notna():

      • notna() 是 Pandas 中的一个方法,用于判断数据是否不是 NaN(即空值)。
      • frame["a"].notna() 返回一个布尔 Series,标识 "a" 列中哪些值不是 NaN
      • 例如,对于 "a" 列中的数据 ["Mozilla/5.0", NaN, "Safari", "Chrome", NaN]notna() 返回 [True, False, True, True, False]
    • frame[frame["a"].notna()]:

      • 使用布尔索引筛选 frame 数据框,仅保留 "a" 列中非空的行。
      • 结果是一个新的数据框,只包含 "a" 列中值不是 NaN 的行。
    • .copy():

      • .copy() 方法用于生成筛选后数据框的一个深拷贝,确保 cframe 是独立的,不会与 frame 共享数据。
      • 这样做是为了防止对 cframe 的操作(如修改数据)影响到原始数据 frame
    • cframe:

      • cframe 是经过筛选和复制的新的数据框,它包含所有 "a" 列非空的行
        cframe = frame[frame["a"].notna()].copy()
        cframe




        这里是删除了所有存在NAN的行


        在数据框 cframe 中创建一个新的列 "os",用于标记每行对应的操作系统是 "Windows" 还是 "Not Windows",根据 "a" 列中是否包含 "Windows" 字样来判断。
         
        cframe["os"] = np.where(cframe["a"].str.contains("Windows"),"Windows", "Not Windows")
        cframe["os"].head(5)

      • cframe["a"].str.contains("Windows"):

        • cframe["a"]:获取 cframe 数据框中的 "a" 列。
        • .str.contains("Windows"):检查 "a" 列中的每个字符串是否包含 "Windows",返回一个布尔 Series。如果包含 "Windows",则为 True;否则为 False
      • np.where(condition, x, y):

        • np.where 是 NumPy 的一个函数,根据 condition 的布尔值来选择 xy
        • 如果 conditionTrue,则返回 x;如果为 False,则返回 y
        • 在这里,根据是否包含 "Windows",分别返回 "Windows""Not Windows"
      • cframe["os"] = np.where(...):

        • np.where(...) 的结果赋值给 cframe 的新列 "os"
        • 这样,"os" 列中的每一行将被标记为 "Windows""Not Windows",取决于 "a" 列的内容。
      • cframe["os"].head(5):

        • .head(5) 用于显示 "os" 列的前 5 行,方便查看标记结果。


      • 对整个dataframe进行按照 “c”,"os"两列分组
        by_c_os = cframe.groupby(["c", "os"])
        print(by_c_os)
      • by_c_os = cframe.groupby(["c", "os"]):

        • 这行代码对 cframe 数据框进行分组,按 c(时区或其他分类)和 os(操作系统)组合分组。
        • by_c_os 是一个分组对象,后续可以对分组数据进行聚合操作。
      • agg_counts = by_c_os.size().unstack().fillna(0):

        • by_c_os.size():计算每个 (c, os) 组合的分组大小(即记录数量)。
        • .unstack():将 os 从行索引转换为列,形成一个 DataFrame,行是 c 的值,列是 os 的值。
        • .fillna(0):用 0 填充 NaN,表示某个 (c, os) 组合没有出现时的计数。
      • agg_counts.head():

        • 显示 agg_counts DataFrame 的前 5 行,方便快速查看分组统计结果。
      • indexer = agg_counts.sum("columns").argsort():

        • agg_counts.sum("columns"):对每一行(每个 c)按列方向求和,即计算各时区中所有操作系统的总计数。
        • .argsort():返回求和结果从小到大的排序索引。
        • indexer 是一个 Index 对象,包含了排序后的索引位置。
      • indexer.values[:10]:

        • 取出 indexer 的前 10 个索引值。这通常用于选择出现次数较少的时区或分类。
      • print(indexer):

        • 打印 indexer,显示排序后的索引。
           
          by_c_os = cframe.groupby(["c", "os"])
          print(by_c_os)
          agg_counts = by_c_os.size().unstack().fillna(0)
          agg_counts.head()
          indexer = agg_counts.sum("columns").argsort()
          indexer.values[:10]
          print(indexer)

           
        • count_subset = agg_counts.take(indexer[-10:]):

          • indexer[-10:]:获取 indexer 的最后 10 个索引。这表示选择排序后计数值最大的 10 个组。
          • agg_counts.take(indexer[-10:]):使用 take() 方法根据 indexer 中的索引提取对应的行。
          • count_subset:是一个新的 DataFrame,包含了 agg_counts 中按总计数排序的最后 10 行数据(即计数最高的 10 组)。
        • agg_counts.sum(axis="columns").nlargest(10):

          • agg_counts.sum(axis="columns"):对 agg_counts 的每一行(即每个 c 组)按列方向求和,得到每个组的总计数。
          • nlargest(10):获取求和后值最大的前 10 个组。
          • 结果是一个包含前 10 个最大值及其对应索引的 Series。

             



      • pandas有⼀个简便⽅法nlargest,可以做同样的⼯作:
        agg_counts.sum(1).nlargest(10)


        (注意的是对a标签 所有 缺失值都delete了 对c标签 缺失值都 fill了)



         

      • count_subset = count_subset.stack():

        • stack() 方法将 count_subset DataFrame 的列索引(os)转为行索引,从而将宽表(Wide Format)转换为长表(Long Format)。
        • 这使得每个时区 (c) 和操作系统 (os) 的组合有各自的行,并且相应的计数值也在同一列中。

        例如,count_subset 经过 stack() 后的效果:

        count_subset = count_subset.stack()
        count_subset.name = "total"
        count_subset = count_subset.reset_index()
        count_subset.head(10)
        sns.barplot(x="total", y="c", hue="os",  data=count_subset)

      • count_subset.name = "total":

        • count_subset 命名为 "total",即将刚刚生成的值列命名为 "total",这对后续的绘图有利。
      • count_subset = count_subset.reset_index():

        • reset_index() 方法将多级索引 (cos) 转为普通的 DataFrame 列,使数据更整洁,并方便后续绘图使用。

      • count_subset.head(10):

        • 显示 count_subset DataFrame 的前 10 行,用于快速查看数据的结构和内容。
      • sns.barplot(x="total", y="c", hue="os", data=count_subset):

        • 使用 seaborn 的 barplot() 函数绘制分组条形图:
          • x="total":将 "total" 列的值作为 X 轴。
          • y="c":将 "c" 列的值作为 Y 轴(时区)。
          • hue="os":根据 "os" 列(操作系统)对数据进行分组和着色。
          • data=count_subset:指定用于绘图的数据源是 count_subset

             
          • 定义函数 norm_total(group):

            • 这是一个自定义函数,用于对每个分组的数据进行处理。
            • group["total"] / group["total"].sum()
              • 计算 group["total"] 中每个值相对于该组内总和的比例。
              • 归一化操作:将每个 total 值除以该组(c)内所有 total 的总和。
            • group["normed_total"] = ...
              • 将计算的归一化比例存储在新的列 "normed_total" 中。
            • return group
              • 返回经过处理的分组数据。
          • count_subset.groupby("c").apply(norm_total):

            • .groupby("c"):将 count_subset"c"(时区)进行分组。
            • .apply(norm_total):对每个分组调用 norm_total() 函数。
            • results 是包含了所有分组及其处理结果的 DataFrame,带有新增的 "normed_total" 列。

            • 还可以⽤ groupby 的transform⽅法,更⾼效的计算标准化的和


              本人为大三本科生,由于时间仓促,本文难免会出现错误或者纰漏!欢迎大家评论区讨论交流!互粉!
               

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.xdnf.cn/news/149589.html

如若内容造成侵权/违法违规/事实不符,请联系一条长河网进行投诉反馈,一经查实,立即删除!

相关文章

复杂网络(Complex Network)社团数据可视化分析(gephi)实验

Experiment Report of complex network course 复杂网络实验报告 目录 Experiment Report of complex network course 复杂网络实验报告 实验目标(The objective of the experiment): 实验流程(The flow of the experiment&a…

实验室ICPR 2024论文分享┆FPMT: 基于增强型半监督模型的交通事件检测(含详细视频解读)

目录 论文分享简介 1. 会议介绍 2. 研究背景及主要贡献 3. 方法 4. 实验 5. 结论 6. 论文介绍视频 论文分享简介 本推文详细介绍了一篇实验室的最新论文成果《FPMT: Enhanced Semi-Supervised Model for Traffic Incident Detection》,该论文已被第27届国际…

23中设计模式,以及三种常见的设计模式demo

常见的23种设计模式 Java设计模式是软件工程中常见的解决方案,用于解决在软件设计中反复出现的问题。设计模式可以分为三大类:创建型模式、结构型模式和行为型模式。这里,我将简单介绍三种常见的设计模式,并给出相应的Java代码示例…

序列化和自定义协议

序言 在上一篇文章中,我们介绍了Socket 编程,已经可以简单地使用该方法来进行服务端和客户端的数据了。在这篇文章中我们将在此基础上学习序列化和反序列化,以及在应用层上自定义协议。 序列化和反序列化 1. 为什么需要序列化和反序列化&…

网页跨域异常100%解决(谷歌浏览器)

目的: 1.开发过程中,经常出现浏览器提示跨域 2.原因新版本浏览器拦截跨域请求 3.错误关键消息如下: Access-Control-Allow-Origin cess to XMLHttpRequest at http://192.168.1.104:3080/api/Login/Store from origin http://yingyongliere…

数据分析学习之学习路线

前言 我们之前通过cda认证了解到数据分析行业,但是获取到证书,并不代表着,我们已经拥有的数据分析的能力,所以通过系统的学习数据分析需要掌握的能力,并学习大佬们的分析经验、分析思路,才是成为数据分析师…

为什么会出现电话机器人?语音电话机器人的出现起到了什么作用?

电话机器人的出现是科技发展与市场需求相结合的产物,它们的广泛应用反映了现代社会对效率、成本和服务质量的不断追求。以下是电话机器人出现的几个主要原因。 1. 市场需求的变化 随着经济的发展和消费模式的转变,客户对服务的期望不断提高。他们希望能…

数据集-目标检测系列-海洋鱼类检测数据集 fish>> DataBall

数据集-目标检测系列-海洋鱼类检测数据集 fish>> DataBall 数据集-目标检测系列-海洋鱼类检测数据集 fish 数据量:1W 数据项目地址: gitcode: https://gitcode.com/DataBall/DataBall-detections-100s/overview github: https://github.com/…

时间序列数据可视化

#时间序列可视化 #离散数据的时间序列可视化 import numpy as np import pandas as pdts pd.Series(np.random.randn(1000), indexpd.date_range(1/1/2000, periods1000)) ts ts.cumsum() ts.plot() #%% #连续数据的时间序列可视化 import matplotlib.pyplot as plt df pd.D…

论文复现:考虑电网交互的风电、光伏与电池互补调度运行(MATLAB-Yalmip-Cplex全代码)

论文复现:考虑电网交互的风电、光伏与电池储能互补调度运行(MATLAB-Yalmip-Cplex全代码) 针对风电、光伏与电化学储能电站互补运行的问题,已有大量通过启发式算法寻优的案例,但工程上更注重实用性和普适性。Yalmip工具箱则是一种基于MATLAB平台的优化软件工具箱,被广泛应用…

AWS注册时常见错误处理

引言 创建AWS账号是使用AWS云服务的第一步,但在注册过程中可能会遇到一些常见的问题。本文中九河云将帮助您排查和解决在创建AWS账户时可能遇到的一些常见问题,包括未接到验证电话、最大失败尝试次数错误以及账户激活延迟等。 常见问题及解决方法 1. …

生成式AI赋能:对话式BI引领数据分析新潮流

引言:数据交互的革新之旅 在信息爆炸的今天,我们与数据交互的方式正经历着前所未有的变革。静态的仪表盘,尽管曾以视觉上的革新引领一时风尚,但如今已难以满足用户对动态、深度数据洞察的迫切需求。用户不再满足于仅仅观赏精美的…

Go weak包前瞻:弱指针为内存管理带来新选择

在介绍Go 1.23引入的unique包的《Go unique包:突破字符串局限的通用值Interning技术实现》一文中,我们知道了unique包底层是基于internal/weak包实现的,internal/weak是一个弱指针功能的Go实现。所谓弱指针(Weak Pointer,也称为弱…

线程池和JUC

1. 线程池 1.1 线程状态介绍 当线程被创建并启动以后,它既不是一启动就进入了执行状态,也不是一直处于执行状态。线程对象在不同的时期有不同的状态。那么Java中的线程存在哪几种状态呢?Java中的线程 状态被定义在了java.lang.Thread.Stat…

C# Socket 服务端

WPF 项目 引入 Socket using System.Net.Sockets; 声明 Socket 并创建对象等待客户端连接 开启线程等待客户端连接并接收消息 接收消息并解析 发送消息 完整代码

【设计模式-访问者模式】

定义 访问者模式(Visitor Pattern)是一种行为型设计模式,允许你在不修改已有类的情况下向这些类添加新的功能或行为。它通过将操作的执行逻辑从对象的类中分离出来,使得你可以在保持类的封闭性(符合开闭原则&#xff…

【有啥问啥】 Self-Play技术:强化学习中的自我进化之道

Self-Play技术:强化学习中的自我进化之道 在人工智能的快速发展中,强化学习(Reinforcement Learning, RL)已成为推动智能体自主学习与优化的关键力量。Self-Play技术,作为强化学习领域的一项前沿创新,通过…

【工作流集成】springboot+vue集成工作流activiti,flowable,智能审批系统,集成方案(源码)

基于Javavue开发的智能审批系统,低代码平台 软件资料清单列表部分文档清单:工作安排任务书,可行性分析报告,立项申请审批表,产品需求规格说明书,需求调研计划,用户需求调查单,用户需…

教育在线答题在线小程序源码系统 PHP+MySQL组合开发源码开源可二次开发 带搭建部署教程

系统概述 教育在线答题在线小程序源码系统是一款专为教育行业设计的,集在线题库管理、智能组卷、在线答题、自动评分、成绩分析等功能于一体的综合性平台。该系统采用PHP作为后端开发语言,结合MySQL数据库进行数据存储与管理,确保了系统的稳…

DC-DC动态响应度的优化

DC-DC动态响应度的优化 以MP2315模块为例到底怎么样才能改变动态响应度呢?修改前馈电容修改电感也可以改善动态响应度 以MP2315模块为例 DC-DC输出位置再增加电容 从下面的波形图看出,多了一颗输出电容之后的结果,似乎有那么一点点作用但是…