Python数据分析实战之用户消费行为数据分析

news2024/11/25 4:41:55

任务1:数据预处理

表格数据资源如下百度网盘👇

链接:https://pan.baidu.com/s/1pUYfRIe557v6O9ByB2rhEw 提取码:ovgl

import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
# %matplotlib inline
# 更改绘图风格,此处是R语言的风格
plt.style.use('ggplot')
image-20221214141834587

数据存放在.txt文件中,属性值没有列名且每列数值以空格作为分隔符

# 读取的 txt 数据中没有列名,因此需要手动添加
coloums=['user_id','order_dt','order_products','order_amount']
# sep='\s+' 表示以任意空格作为不同属性的分隔符
data = pd.read_table('CDNOW_master.txt',names=coloums,sep='\s+')
data
image-20221214142049674
  • user_id:用户 I D ID ID
  • order_dt:购买日期
  • order_products:购买产品数量
  • order_amount:购买金额
# 查看数据一些基本数值信息
data.describe()
image-20221214142618031

任务2:将order_dt列转换为标准日期格式

# format参数:按照指定的格式去匹配要转换的数据列
# %Y:四位的年份     %m:两位的月份     %d:两位的天【几号】
# %y:两位的年份     %h:两位的小时     %M:两位的分钟     %s:两位的秒
data['order_dt']=pd.to_datetime(data['order_dt'],format='%Y%m%d')
data
image-20221214163633249

增添一列month,用来存放年份与月份的日期信息

# month这一列也是存放日期,不过精度只到月份;M 即控制精度到月份
data['month']=data['order_dt'].astype('datetime64[M]')
# data.drop(columns='month',inplace=True)
data
image-20221214164011367

任务3:统计每月产品购买数,消费金额

同年同月的产品购买数,消费金额再相加即可

# 设置画布大小【即绘制的图形大小】
plt.figure(figsize=(12,5))

# 总共绘制1行2列,当前准备绘制第1行第1列的图形
plt.subplot(121)
# 每月的产品购买数量
data.groupby(by='month')['order_products'].sum().plot()
plt.title('每月的产品购买数量')

# # 每月的消费金额
plt.subplot(122)
data.groupby(by='month')['order_amount'].sum().plot()
plt.title('每月的消费金额')
plt.show()
image-20221214165001673

任务4:统计每月的消费次数

# count()统计同一组 user_id 条目出现的个数
data.groupby(by='month')['user_id'].count().plot()
plt.title('每月的消费次数')
plt.show()
image-20221214165544395

任务5:统计每月消费人数

# map()是对Series中的每个具体元素进行映射;apply()是对整个Series进行映射
# 此处将 user_id 去重后再进行人员统计,确保一个用户只被计算一次
data.groupby(by='month')['user_id'].apply(lambda x: len(x.drop_duplicates())).plot()
plt.title('每月的消费人数')
plt.show()
image-20221214165707713

任务6:散点图展示用户购买商品数量与价钱关系

# 将 data 按照 user_id 分组,对于其他列进行求和处理【日期列无法求和,因此被丢弃】
user_id_group = data.groupby(by='user_id').sum()
# 绘制散点图,x 轴为 order_products;y 轴为 order_amount【斜率正好为平均单价】
user_id_group.plot(kind='scatter',x='order_products',y='order_amount')
plt.xlabel('商品总数')
plt.ylabel('商品总价')
plt.show()
image-20221216142416119

任务7:直方图统计订单消费金额与用户购买数量

# 设置画布大小,即绘制图形的大小
plt.figure(figsize=(12,8))
# 总共有1行2列个图,当前画第1个
plt.subplot(121)
# 订单的消费金额
# hist 代表直方图;柱子宽度=(最大值-最小值)/bins,所以bins越大,直方图越细
data['order_amount'].plot(kind='hist',bins=50)
plt.xlabel('每个订单的消费金额')
plt.ylabel('次数')

# 总共有1行2列个图,当前画第2个
plt.subplot(122)
# 每个用户的购买数量
data.groupby(by='user_id')['order_products'].sum().plot(kind='hist',bins=50)
plt.xlabel('每个用户购买数量')
plt.ylabel('次数')
plt.show()
image-20221216143107777

任务8:统计用户消费金额贡献率

8.1 按照用户消费金额进行升序排序

# 按照用户消费金额进行升序排序,合并掉一些条目后索引会乱,因此需要重置索引reset_index
user_sum_amount=data.groupby(by='user_id')['order_amount'].sum().sort_values().reset_index()
user_sum_amount
image-20221216143519037

8.2 增添amount_cumsum列记录用户消费金额累加和

# cumsum()是对列表求前缀和并保存再新列表,如[1,2,3]计算后变[1,3,6]
user_sum_amount['amount_cumsum']=user_sum_amount['order_amount'].cumsum()
user_sum_amount
image-20221216143804609

8.3 增添prop贡献率列

# 所有订单amount的累加和
amount_total = user_sum_amount['amount_cumsum'].max()
# 当前订单的累加和/总累加和 == 贡献率
user_sum_amount['prop']=user_sum_amount['amount_cumsum'].apply(lambda x:x/amount_total)
user_sum_amount
image-20221216144254831

8.4 绘制贡献率折线图

user_sum_amount['prop'].plot()
plt.xlabel('前X名用户')
plt.ylabel('金额贡献率')
plt.show()
image-20221216144342888

任务9:统计用户最早购买时间

# 取出用户的最早购买时间并对相同时间的用户进行计数
data.groupby(by='user_id')['order_dt'].min().value_counts().plot()
plt.xlabel('用户最早购买时间')
plt.ylabel('计数')
plt.show()
image-20221216153218266

任务10:利用RMF模型对用户进行分类

10.1 RMF模型

为了进行精细化运营,可以利用RFM模型对用户价值指数(衡量历史到当前用户贡献的收益)进行计算

  • R(Recency,最近一次消费):R值越大,表示客户交易发生的日期越久,反之则交易发生的日期越近
  • F(Frequency,消费频率):F值越大,表示客户交易越频繁,反之则表示客户交易不够活跃
  • M(Monetary,消费金额):M值越大,表示客户价值越高,反之则表示客户价值越低
image-20221216163855306

RFM计算方式:每一列数据减去数据所在列的平均值,有正有负,根据结果值与 1 做比较,如果 >=1 ,设置为1,否则0

所以最后会生成000~1118种分类结果,如上图👆

# pandas 自带透视表函数【透视表可以理解为对不同列进行不同聚合操作后形成的临时表】
# index指定透视表索引【重复项被合并】;values指定透视表列;aggfunc规定对不同列的聚合函数
rfm = data.pivot_table(index='user_id',
                      values=['order_products','order_amount','order_dt'],
                      aggfunc={
                          'order_products':'sum',  # 用户购买产品总数
                          'order_amount':'sum',   # 用户购买产品总金额
                          'order_dt':'max'   # 用户最后一次消费时间
                      })
rfm.head()
image-20221216185916893
# 增添 R列 记录当前用户最后一次购买时间与统计中最晚一次购买时间相隔的天数
# /np.timedelta64(1,'D')将日期以天数进行存储,并保留1位小数
rfm['R']=(rfm['order_dt'].max()-rfm['order_dt'])/np.timedelta64(1,'D')
# F列 记录当前用户购买的产品总数,正好和order_products一致,因此直接替换;M列的处理同理
rfm.rename(columns={'order_products':'F','order_amount':'M'},inplace=True)
rfm
image-20221216190116551
# 传入的 x 存储了 data 中R,F,M列与对应列平均值的差值
def rfm_func(x):
    # 如果当前差值大于等于1就令新列取1,否则取0
    level = x.apply(lambda x:'1' if x>=1 else '0')
    # 将 level 的三列进行拼接可以得到一个长度为3的二进制字符串
    label=level['R']+level['F']+level['M']
    # 手动创建字典映射
    d={
        '111':'重要价值客户',
        '011':'重要保持客户',
        '101':'重要发展客户',
        '001':'重要挽留客户',
        '110':'一般价值客户',
        '010':'一般保持客户',
        '100':'一般发展客户',
        '000':'一般挽留客户'
    }
    # 按照拼装好的二进制去字典中寻找其对应标签,最后返回的列即不同用户对应的标签
    return d[label]

# lambda中的x实际上取值为R一整列,F一整列,M一整列
# axis为1是以行的方向调用rfm_func函数
rfm['label']=rfm[['R','F','M']].apply(lambda x:x-x.mean()).apply(rfm_func,axis=1)
rfm
image-20221216191104994

10.2 RMF模型散点化

  • 当我们对一个DataFrame进行groupby聚合分组操作时,我们会得到一个DataFrameGroupBy对象
  • DataFrameGroupBy包含若干个tuple
  • tuple中包含两项
    • 第一项是分组时指定的列得到的不同值
    • 第二项是一个DataFrameDataFrame保持着和被聚合的原DataFrame结构一致
# 此处label装载8个标签结果,grouped即分组后的DataFrame
for label,grouped in rfm.groupby(by='label'):
    # 主要为了查看标签散点分布【即哪种类型用户多】,因此x,y轴任取两列即可
    x=grouped['R']   # 单个用户的购买数量
    y=grouped['F']   # 最近一次购买时间与98年7月的相差天数
    plt.scatter(x,y,label=label)
plt.legend()  # 添加图例
plt.ylabel('用户购买数量')
plt.xlabel('用户最近一次购买时间与98年7月的相差天数')
plt.show()
image-20221216191926557

任务11:统计用户在各个月份的消费情况

# 新建透视表,行存放用户在某个月的订单数
pivoted_counts = data.pivot_table(
    index='user_id',
    columns='month',   # month列的取值作为列属性值
    values='order_dt', # order_dt作为列值
    aggfunc={
        'order_dt':'count' # 聚合时对列值使用count函数,结合起来也就是统计用户在某个月的订单数
    }).fillna(0)  # 将NAN空值用0来替换
pivoted_counts
image-20221216214143915
  • apply:作用与dataframe数据中的一行或者一列数据【也就是要有明确的行和列方向】
  • applymap:作用与dataframe数据中的每一个元素
  • map:本身是一个series的函数,在df结构中无法使用map函数,map函数作用于series中每一个元素
# def test_method(x):
#     level = x.apply(lambda x:1 if x>0 else 0)
#     return level
# df_purchase = pivoted_counts.apply(test_method,axis=1)


# 将有进行消费的标记为1,反之标记为0。此处实现方法等价于等价于👆
df_purchase = pivoted_counts.applymap(lambda x:1 if x>0 else 0)
df_purchase
image-20221216214502458

任务12:统计不同类型用户个数

  1. 从未消费过的用户,当下进行第一次消费标记为new【新用户】
  2. 当前月份未进行消费标记未unactive【不活跃用户】
  3. 上个月有消费,这个月也有消费标记未active【活跃用户】
  4. 曾经有消费过,并且上个月未进行消费,这个月进行了消费标记未return【回流用户】
  5. 从未进行过消费的用户标记未unreg【未注册用户】
# data:每一行数据(共18列)
def active_status(data): 
    status = [] #存储用户18个月的状态(new|active|unactive|return|unreg)
    for i in range(18):
        # 本月没有消费
        if data[i] ==0:   # 当前月份 i 没有消费
            if len(status)==0: # 此时对应的是第一个月,肯定从未进行过消费
                status.append('unreg')  
            else: # 第一个月之后的情况
                if status[i-1] =='unreg':#一直没有消费过
                    status.append('unreg')
                else:
                    status.append('unactive')
        # 本月有消费
        else:
            if len(status)==0:
                status.append('new') #第一次消费
            else:# 第一个月之后的情况
                # 说明之前有过消费但是不活跃,此时算回流用户
                if status[i-1]=='unactive': 
                    status.append('return') 
                # 说明之前没有过消费,此时算新用户
                elif  status[i-1]=='unreg': 
                    status.append('new') #第一次消费
                # 说明之前有过消费并且活跃,此时仍然延续活跃状态
                else:   
                    status.append('active') #活跃用户
    # apply函数返回对象应是Series,此处按行处理,因此18个元素需要指定18个列名  
    # df_purchase是任务11最后生成的DataFrame
    return pd.Series(status,df_purchase.columns) # 值:status,列名:18个月份

purchase_states = df_purchase.apply(active_status,axis=1) #得到用户分层结果
purchase_states
image-20221219155402140
# 把 unreg 状态用 Nan 空值替换
purchase_states.replace('unreg',np.NaN,inplace=True)
# 统计每个月份不同类型用户的个数,由于unreg状态已经背替换为Nan,因此此状态个数不会被统计
purchase_states_ct = purchase_states.apply(lambda x:pd.value_counts(x))
purchase_states_ct.head()
image-20221219155449022
# 图表中的Nan实则就是当前月份没有这个状态,即统计次数为0,因此可用0进行替换
purchase_states_ct.fillna(0,inplace=True)
# T代表转置,把原本应该为y轴的month转到x轴显示,另一个方向同理
# 数据可视化,面积图
purchase_states_ct.T.plot.area(figsize=(10,4))  
plt.ylabel('不同类型用户的个数')
plt.show()
image-20221219155733427

任务13:统计回流用户占比情况

# 每月中回流用户占比情况(占所有用户的比例)
plt.figure(figsize=(12,6))
# 默认对表格按列处理,所以rate最后得到的是四行数据,存放每个月不同类型用户占所有用户的比例
rate = purchase_states_ct.apply(lambda x:x/x.sum())
# 转置后列为用户类型,行为月份
rate.T.head()
image-20221219163229355
# pandas直接索引是按列进行取值的,所以绘制状态在不同月份的取值需要用到rate.T
# plot是折线图
plt.plot(rate.T['return'],label='return')
plt.plot(rate.T['active'],label='active')
# 增加图例
plt.legend()
plt.xlabel('月份')
plt.ylabel('所占比例')
plt.show()
image-20221219163442878

任务14:统计用户消费时间间隔

# shift()使得Series整体移动一个单位,如[0,1,2]经过shift后变[Nan,0,1]
# 按照用户ID分类后,用户下次消费时间减去上次消费时间即消费时间间隔
order_diff=data.groupby(by='user_id')['order_dt'].apply(lambda x:x-x.shift())
# 消费时间间隔转换为“天”单位,绘制直方图
(order_diff/np.timedelta64(1,'D')).hist(bins=20)
plt.xlabel('消费时间间隔(天)')
plt.ylabel('用户数')
plt.show()
image-20221219195509925

任务15:统计用户生命周期

所谓生命周期即第一次消费与最后一次消费相隔的天数

# agg()函数内可放置多个聚合函数,此处是生成同一用户'order_dt'列的最小值列和最大值列
user_life = data.groupby(by='user_id')['order_dt'].agg(['min','max'])
user_life
image-20221219202430029
# 统计只消费过一次的人数和消费多次的人数,pie是饼图
# %.1f%%是比例保留一位小数,%%实际是一个百分号;radius是饼的半径
(user_life['max']== user_life['min']).value_counts().plot(kind='pie',autopct='%.1f%%',radius=0.8)
plt.legend(['只消费过一次的人','消费过多次的人'])
plt.show()
image-20221219203727732
plt.figure(figsize=(10,5))
plt.subplot(121)
# 用户最晚消费的时间-最早消费的时间即为此用户生命周期,只消费过一次的用户生命周期长度为0
date_gap=(user_life['max']-user_life['min'])/np.timedelta64(1,'D')
date_gap.plot(kind='hist',bins=15)
plt.title('所有用户生命周期长度统计')
plt.xlabel('生命周期长度')
plt.ylabel('用户数')

plt.subplot(122)
date_gap[date_gap>0].plot(kind='hist',bins=15)
plt.title('多次消费的用户生命周期长度统计')
plt.xlabel('生命周期长度')
plt.ylabel('用户数')
plt.show()
image-20221219210019540

任务16:分析复购率

复购率即当月多次消费的用户数所占当月有过消费的用户数的比例

# 任务11的透视表pivoted_counts存放了用户各个月份的购买情况
pivoted_counts
image-20221216214143915

对上述DataFrame进行二次处理

  • 当月购买次数大于1的标记为1,意思为在当月有复购
  • 当月购买次数等于1的标记为0,意思为没有复购
  • 当月根本没有消费记录的标记为NaN
# lambda中第一个else后所有内容为一个整体
purchase_r = pivoted_counts.applymap(lambda x:1 if x>1 else np.nan if x==0 else 0)
purchase_r
image-20221219214339243
# sum()得到当前月份所有复购用户数;count()得到当前月份所有有消费的用户数
# 二者相除即复购用户占所有消费用户的比例【注:count不会对Nan计数】
(purchase_r.sum()/purchase_r.count()).plot()
plt.ylabel('复购率')
plt.show()
image-20221219214420926

任务17:分析回购率

回购率是指一段时间内【这里的一段时间是两个月】有多次消费的用户数占一段有过消费的用户数的比例,不过同一个月消费多次

# 任务11的最后的df_purchase对用户在每个月是否消费进行了处理
df_purchase
image-20221216214502458

对上述DataFrame进行二次处理

  • 如果当前月消费了,但是下个月没有消费,标记为0,说明在这个月不属于回购用户
  • 如果当前月没有消费标记为NaN
  • 当前月消费了,下个月也消费了标记为1,说明在这个月是回购用户
# 计算方式:在一个时间窗口内进行了消费,在下一个窗口内又进行了消费
def purchase_back(x):
    status = [] # 存储用户回购率状态
    # 1:回购用户   0:非回购用户(当前月消费了,下个未消费)   NaN:当前月份未消费
    for i in range(17):
        # 当前月份消费了
        if x[i] == 1:
            if x[i+1]==1:
                status.append(1) # 回购用户
            elif x[i+1] == 0: # 下个月未消费
                status.append(0)
        else: # 当前月份未进行消费
            status.append(np.NaN)
    # for循环没有处理到最后一个元素,因此需要单独进行处理
    status.append(np.NaN) 
    # 传进来的x是一行数据,因此要给其对应位置加上列名返回
    return pd.Series(status,df_purchase.columns)

purchase_b=df_purchase.apply(purchase_back,axis=1)
purchase_b
image-20221219222152731
plt.figure(figsize=(15,12))
plt.subplot(211)
# 同样这里sum得到当前月份所有用户总共回购的次数,count得到当前月份所有用户有消费的次数,二者相除即为回购率
(purchase_b.sum() / purchase_b.count()).plot(label='回购率')
# 复购率
(purchase_r.sum()/purchase_r.count()).plot(label='复购率')
plt.legend()
plt.ylabel('百分比%')
plt.title('用户回购率和复购率对比图')

# 回购人数与购物总人数
plt.subplot(212)
plt.plot(purchase_b.sum(),label='回购人数')
plt.plot(purchase_b.count(),label='购物总人数')
plt.title('回购总人数与购物总人数对比图')
plt.xlabel('month')
plt.ylabel('人数')
plt.legend()
plt.show()
image-20221219224814235

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

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

相关文章

OrangePi 5 Docker下安装OpenWRT作软路由(同样适用于树莓派等设备)

OrangePi5 Docker下安装OpenWRT作软路由(同样适用于树莓派等设备) 说明 本文的软路由作为家中的二级路由,用一根网线连接主路由的LAN口和二级路由的WAN口(当主路由使用配置类似) 如果你想要作为旁路由或中继路由使用…

VUE中render渲染函数(h函数)

vue在绝大多数情况下都推荐使用模板来编写html结构,但是对于一些复杂场景下需要完全的JS编程能力,这个时候我们就可以使用渲染函数 ,它比模板更接近编译器 vue在生成真实的DOM之前,会将我们的节点转换成VNode,而VNode组合在一起形…

巡更标签 “ PE29_BLE_XG

在我们日常中有一些场景涉及到打卡,比如一个设备需要维护,需要每天有工作人员到现场进行检查或者维护操作,目前普通的做法是弄个二维码到场扫码或者本子记录,用记录的方式明显太落后,容易导致监管不好操作,…

STM32 51单片机——搭建keil5的开发环境(ARM)

知识点:keil/proteus搭建概述、环境搭建 实训day1——12月19日 目录 1 keil安装 1.1 安装KEIL5 安装包 步骤1: 步骤2: 步骤3: 步骤4: 步骤5: 1.2 添加License 步骤1: 步骤2&#xff…

LabVIEW中忽略特定错误

LabVIEW中忽略特定错误 在LabVIEW中收到错误,但已经确认它不会对我的应用程序产生负面影响。如何忽略或清除此错误? LabVIEW程序因为出现错误而中止,但希望代码在收到此错误后继续。怎样才能做到这一点? 解决方案 忽略错误有三…

实验9 利用Wireshark软件分析DHCP

目录 一、实验目的及任务 二、实验环境 三、预备知识 四、实验步骤 五、实验报告内容 一、实验目的及任务 1.通过协议分析进一步明确DHCP报文格式中各字段语法语义; 2.进一步明确DHCP工作原理并能够描述 二、实验环境 联网的计算机;主机操作系…

iead中安装Lombok插件、Lombok注解的使用

Lombok插件安装&#xff1a; 1.pom.xml引入Lombok依赖包&#xff1a; <dependency><groupId>org.projectlombok</groupId><artifactId>lombok</artifactId><version>1.18.10</version></dependency>2.file-setting: 安装Lom…

Python中变量的定义和使用规则

一、如何理解Python中的变量 在解释变量这个东东之前&#xff0c;我先给大家看一组代码&#xff0c;如下图&#xff1a; 上图里面&#xff0c;a作为变量&#xff0c;每次存放的数据和数据类型都不同。看到这里大部分人应该明白了&#xff0c;变量就是随时都可以改变的量&#…

[附源码]计算机毕业设计Python的桌游信息管理系统(程序+源码+LW文档)

该项目含有源码、文档、程序、数据库、配套开发软件、软件安装教程 项目运行 环境配置&#xff1a; Pychram社区版 python3.7.7 Mysql5.7 HBuilderXlist pipNavicat11Djangonodejs。 项目技术&#xff1a; django python Vue 等等组成&#xff0c;B/S模式 pychram管理等…

UG/NX二次开发Siemens官方NXOPEN实例解析—2.2 Selection

列文章目录 UG/NX二次开发Siemens官方NXOPEN实例解析—2.1 AssemblyViewer UG/NX二次开发Siemens官方NXOPEN实例解析—2.2 Selection 列文章目录 文章目录 前言 一、知识点提取 二、案例需求分析 三、程序分析 总结 前言 随着工业智能化的不断发展&#xff0c;UG二次开…

代码随想录训练营第十二天

专题&#xff1a;栈和队列 题目&#xff1a;滑动窗口最大值 给定一个数组 nums&#xff0c;有一个大小为 k 的滑动窗口从数组的最左侧移动到数组的最右侧。你只可以看到在滑动窗口内的 k 个数字。滑动窗口每次只向右移动一位。 返回滑动窗口中的最大值。 题目解析&#xff1a;…

【Flink实时数仓】数据仓库项目实战 《五》流量域来源关键词粒度页面浏览各窗口汇总表 【DWS】

文章目录【Flink实时数仓】数据仓库项目实战 《五》流量域来源关键词粒度页面浏览各窗口汇总表 【DWS】1.1流量域来源关键词粒度页面浏览各窗口汇总表&#xff08;FlinkSQL&#xff09;1.1.1 主要任务1.1.2 思路分析1.1.3 图解1.1.4 代码【Flink实时数仓】数据仓库项目实战 《五…

第七章Servlet

文章目录什么是Servlet为什么需要Servlet从不同角度来看Servlet总过程Servlet之间的继承关系Servlet接口接口中方法GenericServlet抽象方法HttpServlet 抽象子类小结Servlet生命周期从Servlet接口方法开始修改Servlet创建对象的时机Servlet容器Servlet相关的保存作用域request&…

零基础如何学好Python开发?

作为一个零基础小白想学好Python开发应该先确定明确目标、做好学习Python系统规划、选择适合的开发工具、进阶提升学习规划、多练多看加深对Python程序的理解&#xff0c;想入门一门编程语言就需要不断的进行练习。 一、明确目标 很多人在学习Python之前了解很少&#xff0c;很…

ShareSDK 安装教程

一、ShareSDK简介 ShareSDK是一种社会化分享组件&#xff0c;为iOS、Android、WP8 的APP提供社会化功能&#xff0c;集成了一些常用的类库和接口&#xff0c;缩短开发者的开发时间&#xff0c;还有社会化统计分析管理后台。ShareSDK移动开发者服务平台由广州掌淘网络科技有限公…

【C++进阶之路第一卷】预编译头加快编译速度

一、前言 最近在写项目的时候&#xff0c;发现随着项目越来越大&#xff0c;编译需要的时间也越来越长&#xff0c; 然后使用了预编译头&#xff0c;时间减少了很多&#xff01; 这个谁用谁知道&#xff0c;很 Nice&#xff01; 1. 预编译头的原理 简单来说就是将一些你认…

广域网简介、PE/CE/P基本概念理解、PPP协议详细介绍、PAP/CHAP认证介绍与配置、PPPOE会话建立详细介绍并配合实验抓包理解报文交互。

3.1.0 广域网&#xff08;简介、PPP、PAP、CHAP、PPPOE&#xff09; 观前温馨提示&#xff1a; 篇幅较大&#xff0c;本章主要有以下大点&#xff0c;可通过目录与右侧导航跳转观看&#xff1a; &#xff08;1&#xff09;广域网基本概念 &#xff08;2&#xff09;PPP协议介…

【Numpy基础知识】在ndarrays上索引

在ndarrays上索引 来源&#xff1a;Numpy官网&#xff1a;https://numpy.org/doc/stable/user/basics.html 文章目录在ndarrays上索引导包【1】基本索引【2】高级索引【3】结合高级索引和基本索引【3】现场访问【4】展开迭代器索引【5】为索引数组赋值【6】处理程序中可变数量的…

Python3 环境搭建

本章节我们将向大家介绍如何在本地搭建 Python3 开发环境。 Python3 可应用于多平台包括 Windows、Linux 和 Mac OS X。 Unix (Solaris, Linux, FreeBSD, AIX, HP/UX, SunOS, IRIX, 等等。)Win 9x/NT/2000Macintosh (Intel, PPC, 68K)OS/2DOS (多个DOS版本)PalmOSNokia 移动手…

浅谈转行Python的看法,分享我的学习方法

今天跟大家聊一下转行Python的看法和经验。本人之前是做Java开发的&#xff0c;后面因为公司需要Python技术&#xff0c;就接触到了Python&#xff0c;我发现Python比Java更加容易理解&#xff0c;简洁&#xff0c;后面随着Python项目的增多干脆就转行做Python开发了。 Python…