90万条数据玩转RFM用户分析模型
RFM,是一种经典的用户分类、价值分析模型:
R,Rencency,即每个客户有多少天没回购了,可以理解为最近一次购买到现在隔了多少天。
F,Frequency,是每个客户购买了多少次。
M,Monetary,代表每个客户平均购买金额,也可以是累计购买金额。
这三个维度,是RFM模型的精髓所在,帮助我们把混杂一体的客户数据分成标准的8类,然后根据每一类用户人数占比、金额贡献等不同的特征,进行人、货、场三重匹配的精细化运营。
用Python建立RFM模型,整体建模思路分为五步,分别是数据概览、数据清洗、维度打分、分值计算和客户分层。
一:数据概览
开发环境:jupyter Notebook, python 3.6
import pandas as pd
import numpy as np
import os os.chdir('F:\\50mat') df = pd.read_excel('PYTHON-RFM实战数据.xlsx')
df.head()
# 打印结果
品牌名称	买家昵称	付款日期	订单状态	实付金额	邮费	省份	城市	购买数量
0	一只阿木木	棒西瓜皮的店	2019-04-18 11:05:26	交易成功	210	0	北京	北京市	1
1	一只阿木木	8fiona_c8	2019-04-18 11:08:03	交易成功	53	0	上海	上海市	4
2	一只阿木木	3t_1479778131547_04	2019-04-18 11:13:01	交易成功	169	0	上海	上海市	1
3	一只阿木木	0kexintiantian20	2019-04-18 11:13:19	付款以后用户退款成功,交易自动关闭	107	0	北京	北京市	1
4	一只阿木木	ysxxgx	2019-04-18 11:18:07	付款以后用户退款成功,交易自动关闭	254	0	江苏省	苏州市	2
在订单状态中,交易成功、用户退款导致交易关闭的,那还包括其他状态吗?退款订单对于我们模型价值不大,需要在后续清洗中剔除。
df['订单状态'].unique()
# 打印结果
array(['交易成功', '付款以后用户退款成功,交易自动关闭', '订单状态'], dtype=object)
再观察数据的类型和缺失情况:
df.info()
# 打印结果
<class 'pandas.core.frame.DataFrame'>
RangeIndex: 922658 entries, 0 to 922657
Data columns (total 9 columns):
品牌名称    922658 non-null object
买家昵称    922658 non-null object
付款日期    922658 non-null object
订单状态    922658 non-null object
实付金额    922658 non-null object
邮费      922658 non-null object
省份      922658 non-null object
城市      922626 non-null object
购买数量    922658 non-null object
dtypes: object(9)
memory usage: 31.7+ MB
数据类型方面,付款日期是时间格式,实付金额、邮费和购买数量是数值型,其他均为字符串类型。
二:数据清洗
2.1 剔除退款
在观察阶段,我们明确了第一个清洗的目标,就是剔除退款数据:
df = df.loc[df['订单状态'] == '交易成功',:]
print('剔除退款后还剩:%d行' % len(df))
打印结果
剔除退款后还剩:889372行
2.2 关键字段提取
剔除之后,觉得我们订单的字段还是有点多,而RFM模型只需要买家昵称,付款时间和实付金额这3个关键字段,所以提取之:
df = df[['买家昵称','付款日期','实付金额']]
df.head()
# 打印结果
买家昵称	付款日期	实付金额
0	棒西瓜皮的店	2019-04-18 11:05:26	210
1	8fiona_c8	2019-04-18 11:08:03	53
2	3t_1479778131547_04	2019-04-18 11:13:01	169
7	2jill27	2019-01-01 10:00:11	121
8	yjessieni	2019-01-01 10:00:14	211
2.3 关键字段构造
R 值构造 。
R值,即每个用户最后一次购买时间距今多少天。
- 如果用户只下单过一次,用现在的日期减去付款日期即可;
- 若是用户多次下单,需先筛选出这个用户最后一次付款的时间,再用今天减去它。
距离今天越近,时间也就越“大”,
 pd.to_datetime('2019-11-11') > pd.to_datetime('2019-1-1') 
 # 打印结果
 True
用户最近一次付款时间,只需要按买家昵称分组,再选取付款日期的最大值即可:
r = df.groupby('买家昵称')['付款日期'].max().reset_index()
r.head()
#打印结果
	买家昵称	付款日期
0	.blue_ram	2019-02-04 17:49:34.000
1	.christiny	2019-01-29 14:17:15.000
2	.willn1	2019-01-11 03:46:18.000
3	.托托m	2019-01-11 02:26:33.000
4	0000妮	2019-06-28 16:53:26.458
用今天减去每位用户最近一次付款时间,就得到R值了,测试样本数据是1月至6月上半年的数据,所以我们把“2019-7-1”当作“今天”:
r['R'] = (pd.to_datetime('2019-7-1') - r['付款日期']).dt.days
r = r[['买家昵称','R']]
r.head()
#打印结果
买家昵称	R
0	.blue_ram	146
1	.christiny	152
2	.willn1	170
3	.托托m	170
4	0000妮	2
F 值构造
F值,即每个用户累计购买频次。
我们明确“单个用户一天内多次下单行为看作整体一次”,引入一个精确到天的日期标签,依照“买家昵称”和“日期标签”进行分组,把每个用户一天内的多次下单行为合并
统计购买次数:
# F 值构造 # 引入日期标签
df['日期标签'] = df['付款日期'].astype(str).str[:10] #把单个用户一天内订单合并
dup_f = df.groupby(['买家昵称','日期标签'])['付款日期'].count().reset_index() #对合并后的用户统计频次
f = dup_f.groupby('买家昵称')['付款日期'].count().reset_index()
f.columns = ['买家昵称','F']
f.head()
# 打印结果
买家昵称	F
0	.blue_ram	1
1	.christiny	1
2	.willn1	1
3	.托托m	1
4	0000妮	1
M 值构造
客户平均购买金额,需要得到每个用户总金额,再用总金额除以购买频次即可。
# M 值构造
sum_m = df.groupby('买家昵称')['实付金额'].sum().reset_index()
sum_m.columns = ['买家昵称','总支付金额']
com_m = pd.merge(sum_m,f,left_on = '买家昵称',right_on = '买家昵称',how = 'inner') #计算用户平均支付金额
com_m['M'] = com_m['总支付金额'] / com_m['F']
com_m.head()
# 打印结果
买家昵称	总支付金额	F	M
0	.blue_ram	1568	1	1568.0
1	.christiny	5856	1	5856.0
2	.willn1	1088	1	1088.0
3	.托托m	1184	1	1184.0
4	0000妮	5248	1	5248.0
R F M 三值合并
# R F M 值构造并合并
rfm = pd.merge(r,com_m,left_on = '买家昵称',right_on = '买家昵称',how = 'inner')
rfm = rfm[['买家昵称','R','F','M']]
rfm.head()
# 打印结果
	买家昵称	R	F	M
0	.blue_ram	146	1	1568.0
1	.christiny	152	1	5856.0
2	.willn1	170	1	1088.0
3	.托托m	170	1	1184.0
4	0000妮	2	1	5248.0
三:维度打分
此部分不涉及代码。
维度确认的核心是分值确定,按照设定的标准,我们给每个消费者的R/F/M值打分,分值的大小取决于我们的偏好,即我们越喜欢的行为,打的分数就越高:
- R值 用户有多少天没来下单,所以R越大,用户流失的可能性越大,分值越小。
- F值 用户购买频次,数值越大,得分越高
- M值 用户平均支付金额,数值越大,得分越高
RFM模型中打分一般采取5分制,有两种比较常见的方式,
- 一种是按照数据的分位数来打分
- 一种是依据数据和业务的理解进行分值的划分
这里使用的是第二种,即提前制定好不同数值对应的分值,加深对数据的理解。
R值根据行业经验,设置为30天一个跨度,区间左闭右开:
| R 分 | R 值 | 
|---|---|
| 1 | [120, +%) | 
| 2 | [90, 120) | 
| 3 | [60, 90) | 
| 4 | [30, 60) | 
| 5 | [0, 30) | 
F值 F值和购买频次挂钩,每多一次购买,分值就多加一分:
| F 分 | F 值 | 
|---|---|
| 1 | 1 | 
| 2 | 2 | 
| 3 | 3 | 
| 4 | 4 | 
| 5 | [5, +%) | 
M值 先对M值做个简单的区间统计,然后分组,这里我们按照1600元的一个区间来进行划分:
| M 分 | M 值 | 
|---|---|
| 1 | [0, 1600) | 
| 2 | [1600, 3200) | 
| 3 | [3200, 4800) | 
| 4 | [4800, 6400) | 
| 5 | [6400, +%) | 
我们确定了一个打分框架,每一位用户的每个指标,都有了与之对应的分值。
四:分值计算
第一次计算
R值:
# 4 R 值计算 rfm['R-SCORE'] = pd.cut(rfm['R'],bins = [0,30,60,90,120,1000000],labels = [5,4,3,2,1],right = False).astype(float)
rfm.head()
# 打印结果
买家昵称	R	F	M	R-SCORE
0	.blue_ram	146	1	1568.0	1.0
1	.christiny	152	1	5856.0	1.0
2	.willn1	170	1	1088.0	1.0
3	.托托m	170	1	1184.0	1.0
4	0000妮	2	1	5248.0	5.0
F M 值计算
# F M 值计算
rfm['F-SCORE'] = pd.cut(rfm['F'],bins = [1,2,3,4,5,1000000],labels = [1,2,3,4,5],right = False).astype(float)
rfm['M-SCORE'] = pd.cut(rfm['M'],bins = [0,1600,3200,4800,6400,10000000],labels = [1,2,3,4,5],right = False).astype(float)
rfm.head()
# 打印结果
买家昵称	R	F	M	F-SCORE	M-SCORE
0	.blue_ram	146	1	1568.0	1.0	1.0
1	.christiny	152	1	5856.0	1.0	4.0
2	.willn1	170	1	1088.0	1.0	1.0
3	.托托m	170	1	1184.0	1.0	1.0
4	0000妮	2	1	5248.0	1.0	4.0
第二次计算
过多的分类和不分类本质是一样的。所以,我们通过判断每个客户的R、F、M值是否大于平均值,来简化分类结果。
因为每个客户和平均值对比后的R、F、M,只有0和1(0表示小于平均值,1表示大于平均值)两种结果,整体组合下来共有8个分组,是比较合理的一个情况。我们来判断用户的每个分值是否大于平均值:
# 第二次计算
rfm['R是否大于均值'] = (rfm['R-SCORE'] > rfm['R-SCORE'].mean()) * 1
rfm['F是否大于均值'] = (rfm['F-SCORE'] > rfm['F-SCORE'].mean()) * 1
rfm['M是否大于均值'] = (rfm['M-SCORE'] > rfm['M-SCORE'].mean()) * 1
rfm.head()
# 打印结果
买家昵称	R	F	M	R-SCORE	F-SCORE	M-SCORE	R是否大于均值	F是否大于均值	M是否大于均值
0	.blue_ram	146	1	1568.0	1.0	1.0	1.0	0	0	0
1	.christiny	152	1	5856.0	1.0	1.0	4.0	0	0	1
2	.willn1	170	1	1088.0	1.0	1.0	1.0	0	0	0
3	.托托m	170	1	1184.0	1.0	1.0	1.0	0	0	0
4	0000妮	2	1	5248.0	5.0	1.0	4.0	1	0	1
代码为什么 * 1,这是由于Python中判断后返回的结果是True和False,对应着数值1和0,只要把这个布尔结果乘上1,True就变成了1,False变成了0,处理之后更加易读。
知识点:
Pandas的cut函数:
- 第一个参数传入要切分的数据列。
- bins参数代表我们按照什么区间进行分组,上面我们已经确定了R值按照30天的间隔进行分组,输入[0,30,60,90,120,1000000]即可,最后一个数值设置非常大,是为了给分组一个容错空间,允许出现极端大的值。
- right表示了右侧区间是开还是闭,即包不包括右边的数值,如果设置成False,就代表[0,30),包含左侧的分组数据而不含右侧,若设置为True,则是[0,30],首尾都包含。
- labels和bins切分的数组前后呼应,什么意思呢?bins设置了6个数值,共切分了5个分组,labels则分别给每个分组打标签,0-30是5分,30-60是4分,依此类推。
五:客户分层
清洗完之后我们确定了打分逻辑,然后分别计算每个用户的R、F、M分值(SCORE),随后,用分值和对应的平均值进行对比,得到了是否大于均值的三列结果。那么客户分层如何处理呢。
| R 大于均值 | F 大于均值 | M 大于均值 | 一般分类 | RFM 分类 | 释义 | 
|---|---|---|---|---|---|
| 1 | 1 | 1 | 重要价值客户 | 重要价值客户 | 近购、高频、高消费 | 
| 1 | 1 | 0 | 重要潜力客户 | 消费潜力客户 | 近购、高频、低消费 | 
| 1 | 0 | 1 | 重要深耕客户 | 频次深耕客户 | 近购、低频、高消费 | 
| 1 | 0 | 0 | 新客户 | 新客户 | 近购、低频、低消费 | 
| 0 | 1 | 1 | 重要唤回客户 | 重要价值流失预警客户 | 近未购、高频、高消费 | 
| 0 | 1 | 0 | 一般客户 | 一般客户 | 近未购、高频、低消费 | 
| 0 | 0 | 1 | 重要挽回客户 | 高消费唤回客户 | 近未购、低频、高消费 | 
| 0 | 0 | 0 | 流失客户 | 流失客户 | 近未购、低频、低消费 | 
潜力是针对消费(平均支付金额),深耕是为了提升消费频次,以及重要唤回客户其实和重要价值客户非常相似,只是最近没有回购了而已,应该做流失预警等等。
5.1 构建合并指标
先引入一个人群数值的辅助列,把之前判断的R\F\M是否大于均值的三个值给串联起来:
# 5 客户分层,构建合并指标 rfm['人群数值'] = (rfm['R是否大于均值'] * 100) + (rfm['F是否大于均值'] * 10) + (rfm['M是否大于均值'] * 1)
rfm.head()
# 打印结果
买家昵称	R	F	M	R-SCORE	F-SCORE	M-SCORE	R是否大于均值	F是否大于均值	M是否大于均值	人群数值
0	.blue_ram	146	1	1568.0	1.0	1.0	1.0	0	0	0	0
1	.christiny	152	1	5856.0	1.0	1.0	4.0	0	0	1	1
2	.willn1	170	1	1088.0	1.0	1.0	1.0	0	0	0	0
3	.托托m	170	1	1184.0	1.0	1.0	1.0	0	0	0	0
4	0000妮	2	1	5248.0	5.0	1.0	4.0	1	0	1	101
人群数值是数值类型,所以位于前面的0就自动略过,比如1代表着“001”的高消费唤回客户人群,10对应着“010”的一般客户。
5.2 基于指标给客户打标签
为了得到最终人群标签,再定义一个判断函数,通过判断人群数值的值,来返回对应的分类标签:
#判断R/F/M是否大于均值
def transform_label(x):
if x == 111:
label = '重要价值客户'
elif x == 110:
label = '消费潜力客户'
elif x == 101:
label = '频次深耕客户'
elif x == 100:
label = '新客户'
elif x == 11:
label = '重要价值流失预警客户'
elif x == 10:
label = '一般客户'
elif x == 1:
label = '高消费唤回客户'
elif x == 0:
label = '流失客户'
return label
5.3 标签应用
rfm['人群类型'] = rfm['人群数值'].apply(transform_label)
rfm.head()
# 打印结果
买家昵称	R	F	M	R-SCORE	F-SCORE	M-SCORE	R是否大于均值	F是否大于均值	M是否大于均值	人群数值	人群类型
0	.blue_ram	146	1	1568.0	1.0	1.0	1.0	0	0	0	0	流失客户
1	.christiny	152	1	5856.0	1.0	1.0	4.0	0	0	1	1	高消费唤回客户
2	.willn1	170	1	1088.0	1.0	1.0	1.0	0	0	0	0	流失客户
3	.托托m	170	1	1184.0	1.0	1.0	1.0	0	0	0	0	流失客户
4	0000妮	2	1	5248.0	5.0	1.0	4.0	1	0	1	101	频次深耕客户
RFM 建模,每一位客户都有了属于自己的RFM标签。
六:RFM 模型结果探索性分析
切模型结果最终都要服务于业务,所以我们基于现有模型结果做一些拓展、探索性分析。
6.1 人数统计
# 6.1 人数分析
count = rfm['人群类型'].value_counts().reset_index()
count.columns = ['客户类型','人数']
count['人数占比'] = count['人数'] / count['人数'].sum()
count
# 打印结果
客户类型	人数	人数占比
0	高消费唤回客户	7338	0.288670
1	流失客户	6680	0.262785
2	频次深耕客户	5427	0.213493
3	新客户	4224	0.166168
4	重要价值客户	756	0.029740
5	消费潜力客户	450	0.017703
6	重要价值流失预警客户	360	0.014162
7	一般客户	185	0.007278
6.2 金额统计
# 6.2 金额分析
rfm['购买总金额'] = rfm['F'] * rfm['M']
mon = rfm.groupby('人群类型')['购买总金额'].sum().reset_index()
mon.columns = ['客户类型','消费金额']
mon['金额占比'] = mon['消费金额'] / mon['消费金额'].sum()
mon
# 打印结果
客户类型	消费金额	金额占比
0	一般客户	825696.0	0.007349
1	新客户	8667808.0	0.077143
2	流失客户	14227744.0	0.126625
3	消费潜力客户	2050506.0	0.018249
4	重要价值客户	8615698.0	0.076679
5	重要价值流失预警客户	3732550.0	0.033219
6	频次深耕客户	31420996.0	0.279644
7	高消费唤回客户	42819846.0	0.381092
6.3 客户类型
result = pd.merge(count,mon,left_on = '客户类型',right_on = '客户类型')
result
# 打印结果
客户类型	人数	人数占比	消费金额	金额占比
0	高消费唤回客户	7338	0.288670	42819846.0	0.381092
1	流失客户	6680	0.262785	14227744.0	0.126625
2	频次深耕客户	5427	0.213493	31420996.0	0.279644
3	新客户	4224	0.166168	8667808.0	0.077143
4	重要价值客户	756	0.029740	8615698.0	0.076679
5	消费潜力客户	450	0.017703	2050506.0	0.018249
6	重要价值流失预警客户	360	0.014162	3732550.0	0.033219
7	一般客户	185	0.007278	825696.0	0.007349
七:模型封装 ENTER
模型封装,一个回车就能返回结果
import pandas as pd
import numpy as np
import os os.chdir('F:\\50mat') #输入源数据文件名
def get_rfm(name = 'PYTHON-RFM实战数据.xlsx'):
# 数据概览
df = pd.read_excel(name)
# 数据清洗
df = df.loc[df['订单状态'] == '交易成功',:]
print('剔除退款后还剩:%d行' % len(df))
df = df[['买家昵称','付款日期','实付金额']] # 构造 R 值,Recency 即每个用户最后一次购买时间距今多少天。
r = df.groupby('买家昵称')['付款日期'].max().reset_index()
r['R'] = (pd.to_datetime('2019-7-1') - r['付款日期']).dt.days
r = r[['买家昵称','R']] # 构造 F 值,Frequency 即每个用户累计购买频次。
#引入日期标签辅助列
df['日期标签'] = df['付款日期'].astype(str).str[:10] #把单个用户一天内订单合并
dup_f = df.groupby(['买家昵称','日期标签'])['付款日期'].count().reset_index() #对合并后的用户统计频次
f = dup_f.groupby('买家昵称')['付款日期'].count().reset_index()
f.columns = ['买家昵称','F'] # M 值构造,Monetary 客户平均购买金额
sum_m = df.groupby('买家昵称')['实付金额'].sum().reset_index()
sum_m.columns = ['买家昵称','总支付金额']
com_m = pd.merge(sum_m,f,left_on = '买家昵称',right_on = '买家昵称',how = 'inner') #计算用户平均支付金额
com_m['M'] = com_m['总支付金额'] / com_m['F'] rfm = pd.merge(r,com_m,left_on = '买家昵称',right_on = '买家昵称',how = 'inner')
rfm = rfm[['买家昵称','R','F','M']] rfm['R-SCORE'] = pd.cut(rfm['R'],bins = [0,30,60,90,120,1000000],labels = [5,4,3,2,1],right = False).astype(float)
rfm['F-SCORE'] = pd.cut(rfm['F'],bins = [1,2,3,4,5,1000000],labels = [1,2,3,4,5],right = False).astype(float)
rfm['M-SCORE'] = pd.cut(rfm['M'],bins = [0,1600,3200,4800,6400,10000000],labels = [1,2,3,4,5],right = False).astype(float) rfm['R是否大于均值'] = (rfm['R-SCORE'] > rfm['R-SCORE'].mean()) * 1
rfm['F是否大于均值'] = (rfm['F-SCORE'] > rfm['F-SCORE'].mean()) * 1
rfm['M是否大于均值'] = (rfm['M-SCORE'] > rfm['M-SCORE'].mean()) * 1 rfm['人群数值'] = (rfm['R是否大于均值'] * 100) + (rfm['F是否大于均值'] * 10) + (rfm['M是否大于均值'] * 1) rfm['人群类型'] = rfm['人群数值'].apply(transform_label) count = rfm['人群类型'].value_counts().reset_index()
count.columns = ['客户类型','人数']
count['人数占比'] = count['人数'] / count['人数'].sum() rfm['购买总金额'] = rfm['F'] * rfm['M']
mon = rfm.groupby('人群类型')['购买总金额'].sum().reset_index()
mon.columns = ['客户类型','消费金额']
mon['金额占比'] = mon['消费金额'] / mon['消费金额'].sum() result = pd.merge(count,mon,left_on = '客户类型',right_on = '客户类型') return result #判断R/F/M是否大于均值
def transform_label(x):
if x == 111:
label = '重要价值客户'
elif x == 110:
label = '消费潜力客户'
elif x == 101:
label = '频次深耕客户'
elif x == 100:
label = '新客户'
elif x == 11:
label = '重要价值流失预警客户'
elif x == 10:
label = '一般客户'
elif x == 1:
label = '高消费唤回客户'
elif x == 0:
label = '流失客户'
return label res = get_rfm(name = 'PYTHON-RFM实战数据.xlsx')
res
# 打印结果
剔除退款后还剩:889372行
客户类型	人数	人数占比	消费金额	金额占比
0	高消费唤回客户	7338	0.288670	42819846.0	0.381092
1	流失客户	6680	0.262785	14227744.0	0.126625
2	频次深耕客户	5427	0.213493	31420996.0	0.279644
3	新客户	4224	0.166168	8667808.0	0.077143
4	重要价值客户	756	0.029740	8615698.0	0.076679
5	消费潜力客户	450	0.017703	2050506.0	0.018249
6	重要价值流失预警客户	360	0.014162	3732550.0	0.033219
7	一般客户	185	0.007278	825696.0	0.007349
by:一只阿木木90万条数据玩转RFM用户分析模型的更多相关文章
- JavaScript如何一次性展示几万条数据
		有一位同事跟大家说他在网上看到一道面试题:“如果后台传给前端几万条数据,前端怎么渲染到页面上?”,如何回答? 于是办公室沸腾了, 同事们讨论开了, 你一言我一语说出自己的方案. 有的说直接循环遍历生成 ... 
- (转)Python网络爬虫实战:世纪佳缘爬取近6万条数据
		又是一年双十一了,不知道从什么时候开始,双十一从“光棍节”变成了“双十一购物狂欢节”,最后一个属于单身狗的节日也成功被攻陷,成为了情侣们送礼物秀恩爱的节日. 翻着安静到死寂的聊天列表,我忽然惊醒,不行 ... 
- Mvc+Dapper+存储过程分页10万条数据
		10万条数据采用存储过程分页实现(Mvc+Dapper+存储过程) 有时候大数据量进行查询操作的时候,查询速度很大强度上可以影响用户体验,因此自己简单写了一个demo,简单总结记录一下: 技术:Mvc ... 
- mysql快速导入5000万条数据过程记录(LOAD DATA INFILE方式)
		mysql快速导入5000万条数据过程记录(LOAD DATA INFILE方式) 首先将要导入的数据文件top5000W.txt放入到数据库数据目录/var/local/mysql/data/${d ... 
- [Python] 通过采集两万条数据,对《无名之辈》影评分析
		一.说明 本文主要讲述采集猫眼电影用户评论进行分析,相关爬虫采集程序可以爬取多个电影评论. 运行环境:Win10/Python3.5. 分析工具:jieba.wordcloud.pyecharts.m ... 
- 绝对干货,教你4分钟插入1000万条数据到mysql数据库表,快快进来
		我用到的数据库为,mysql数据库5.7版本的 1.首先自己准备好数据库表 其实我在插入1000万条数据的时候遇到了一些问题,现在先来解决他们,一开始我插入100万条数据时候报错,控制台的信息如下: ... 
- 1000万条数据导入mysql
		今天需要将一个含有1000万条数据的文本内容插入到数据库表中,最初自然想到的是使用Insertinto '表名'values(),(),()...这种插入方式,但是发现这种方式对1000万条数据量的情 ... 
- QTreeView处理大量数据(使用1000万条数据,每次都只是部分刷新)
		如何使QTreeView快速显示1000万条数据,并且内存占用量少呢?这个问题困扰我很久,在网上找了好多相关资料,都没有找到合理的解决方案,今天在这里把我的解决方案提供给朋友们,供大家相互学习. 我开 ... 
- 极限挑战—C#+ODP 100万条数据导入Oracle数据库仅用不到1秒
		链接地址:http://www.cnblogs.com/armyfai/p/4646213.html 要:在这里我们将看到的是C#中利用ODP实现在Oracle数据库中瞬间导入百万级数据,这对快速批量 ... 
随机推荐
- HelloTalk 基于 OpenResty 的全球化探索之路
			2019 年 12 月 14 日,又拍云联合 Apache APISIX 社区举办 API 网关与高性能服务最佳实践丨Open Talk 广州站活动,HelloTalk, Inc. 后台技术负责人李凌 ... 
- 【转】Matlab多项式拟合
			转:https://blog.csdn.net/hwecc/article/details/80308397 例: x = [0.33, 1.12, 1.41, 1.71, 2.19] y = [0. ... 
- Netty 的基本简单实例【服务端-客户端通信】
			Netty是建立在NIO基础之上,Netty在NIO之上又提供了更高层次的抽象. 在Netty里面,Accept连接可以使用单独的线程池去处理,读写操作又是另外的线程池来处理. Accept连接和读写 ... 
- 原型,原型链,给予原型和class的继承
			学习react的时候遇到了class方式的继承语法,原理和代码的解释很详细,值得一读. 原型每个函数(构造函数)都有一个 prototype 属性,指向该函数(构造函数)的原型对象.实例没有 prot ... 
- try catch 自定义捕获异常
			当我们完成一个程序时,如果没有异常捕获的话,用户使用时会出现许多bug.而加入异常捕获之后便会提醒用户使用时避免产生不必要的错误.具体操作实现如下: 首先创造一个MyException类,继承自Exc ... 
- Java架构师中的内存溢出和内存泄露是什么?实际操作案例!
			JAVA中的内存溢出和内存泄露分别是什么,有什么联系和区别,让我们来看一看. 01 内存泄漏 & 内存溢出 1.内存泄漏(memory leak ) 申请了内存用完了不释放,比如一共有 102 ... 
- 洛谷 p3834 主席树
			题目链接:https://www.luogu.org/problem/P3834 主席树求静态区间第k小 #include<iostream> #include<cstdio> ... 
- python 进程Queue
			1.作用:进程之间的数据交互 2.常用方法 """ 对象.put() 作用:放入队列一个数据 对象.get() 作用:取队列一个数据,若队列没有值,则阻塞 对象.empt ... 
- Error:Cannot build artifact 'XXX:war exploded' because it is included into a circular dependency (artifact 'XXXX:war exploded', artifact 'XXX:war exploded') Idea启动项目报错解决方案
			在Idea中使用Maven创建父子工程,第一个Model的那个项目可以很好的运行,在创建一个Model运行时报这个错.原因是tomcat部署了多个Web项目,可能最开始是两个项目的配置文件混用用,最后 ... 
- OpenCV在Mac下的部署 Java-IntelliJ IDEA
			目录 Xcode Command Line Xcode的证书许可 MacPorts的安装 环境变量的配置 安装OpenCV 安装确认 Idea配置 额外可能产生的问题 Xcode Command Li ... 
