数据分析-03
处理普通文本
读取文本:read_csv() read_table()
方法参数 | 参数解释 |
---|---|
filepath_or_buffer | 文件路径 |
sep | 列之间的分隔符。read_csv()默认为为’,’, read_table()默认为’\t’ |
header | 默认将首行设为列名。header=None 时应手动给出列名。 |
names | header=None 时设置此字段使用列表初始化列名。 |
index_col | 将某一列作为行级索引。若使用列表,则设置复合索引。 |
usecols | 选择读取文件中的某些列。设置为为相应列的索引列表。 |
skiprows | 跳过行。可选择跳过前n行或给出跳过的行索引列表。 |
encoding | 编码。 |
写入文本:dataFrame.to_csv()
方法参数 | 参数解释 |
---|---|
filepath_or_buffer | 文件路径 |
sep | 列之间的分隔符。默认为’,’ |
na_rep | 写入文件时dataFrame中缺失值的内容。默认空字符串。 |
columns | 定义需要写入文件的列。 |
header | 是否需要写入表头。默认为True。 |
index | 会否需要写入行索引。默认为True。 |
encoding | 编码。 |
案例:读取电信数据集。
pd.read_csv('../data/CustomerSurvival.csv', header=None, index_col=0)
处理JSON
读取json:read_json()
方法参数 | 参数解释 |
---|---|
filepath_or_buffer | 文件路径 |
encoding | 编码。 |
案例:读取电影评分数据:
pd.read_json('../data/ratings.json')
写入json:to_json()
方法参数 | 参数解释 |
---|---|
filepath_or_buffer | 文件路径; 若设置为None,则返回json字符串 |
orient | 设置面向输出格式:[‘records’, ‘index’, ‘columns’, ‘values’] |
案例:
data = {'Name':['Tom', 'Jack', 'Steve', 'Ricky'],'Age':[28,34,29,42]}
df = pd.DataFrame(data, index=['s1','s2','s3','s4'])
df.to_json(orient='records')
其他文件读取方法参见:https://www.pypandas.cn/docs/user_guide/io.html
数值型描述统计(统计学)
算数平均值
$S = [s_1, s_2, …, s_n] $
样本中的每个值都是真值与误差的和。
m e a n = ( s 1 + s 2 + . . . + s n ) n mean = \frac{(s_1 + s_2 + ... + s_n) }{n} mean=n(s1+s2+...+sn)
算数平均值表示对真值的无偏估计。
m = np.mean(array)
m = array.mean()
m = df.mean(axis=0)
案例:针对电影评分数据做均值分析:
mean = ratings['John Carson'].mean()
mean = np.mean(ratings['John Carson'])
means = ratings.mean(axis=1)
加权平均值
求平均值时,考虑不同样本的重要性,可以为不同的样本赋予不同的权重。
样本: S = [ s 1 , s 2 , s 3 . . . s n ] S = [s_1, s_2, s_3 ... s_n] S=[s1,s2,s3...sn]
权重: W = [ w 1 , w 2 , w 3 . . . w n ] W =[w_1, w_2, w_3 ... w_n] W=[w1,w2,w3...wn]
加权平均值:
a
=
s
1
w
1
+
s
2
w
2
+
.
.
.
+
s
n
w
n
w
1
+
w
2
+
.
.
.
+
w
n
a = \frac{s_1w_1 + s_2w_2 + ... + s_nw_n}{w_1+w_2+...+w_n}
a=w1+w2+...+wns1w1+s2w2+...+snwn
代码实现:
a = np.average(array, weights=volumes)
案例:自定义权重,求加权平均。
# 加权均值
w = np.array([3,1,1,1,1,1,1])
np.average(ratings.loc['Inception'], weights=w)
mask = ~pd.isna(ratings.loc['Inception'])
np.average(ratings.loc['Inception'][mask], weights=w[mask])
最值
np.max() / np.min() / np.ptp(): 返回一个数组中最大值/最小值/极差(最大值减最小值)
import numpy as np
# 产生9个介于[10, 100)区间的随机数
a = np.random.randint(10, 100, 9)
print(a)
print(np.max(a), np.min(a), np.ptp(a))
np.argmax() np.argmin(): 返回一个数组中最大/最小元素的下标
print(np.argmax(a), np.argmin(a))
print(series.idxmax(), series.idxmin())
print(dataframe.idxmax(), dataframe.idxmin())
np.maximum() np.minimum(): 将两个同维数组中对应元素中最大/最小元素构成一个新的数组
print(np.maximum(a, b), np.minimum(a, b), sep='\n')
中位数
将多个样本按照大小排序,取中间位置的元素。
若样本数量为奇数,中位数为最中间的元素
[ 1 , 2000 , 3000 , 4000 , 10000000 ] [1, 2000, 3000, 4000, 10000000] [1,2000,3000,4000,10000000]
若样本数量为偶数,中位数为最中间的两个元素的平均值
[ 1 , 2000 , 3000 , 4000 , 5000 , 10000000 ] [1,2000,3000,4000,5000,10000000] [1,2000,3000,4000,5000,10000000]
案例:分析中位数的算法,测试numpy提供的中位数API:
import numpy as np
closing_prices = np.loadtxt('../../data/aapl.csv',
delimiter=',', usecols=(6), unpack=True)
size = closing_prices.size
sorted_prices = np.msort(closing_prices)
median = (sorted_prices[int((size - 1) / 2)] +
sorted_prices[int(size / 2)]) / 2
print(median)
median = np.median(closing_prices)
print(median)
频数与众数
频数指一组数据中各离散值出现的次数,而众数则是指一组数据中出现次数最多的值。
cars = np.array(['bmw', 'bmw', 'bz', 'audi', 'bz', 'bmw'])
cars = pd.Series(cars)
cars.value_counts()
cars.mode()
四分位数
所谓四分位数,即把数值由小到大排列并分成四等份,处于三个分割点位置的数值就是四分位数。
- 第1四分位数 (Q1),又称“较小四分位数”,等于该样本中所有数值由小到大排列后第25%的数字。
- 第2四分位数 (Q2),又称“中位数”,等于该样本中所有数值由小到大排列后第50%的数字。
- 第3四分位数 (Q3),又称“较大四分位数”,等于该样本中所有数值由小到大排列后第75%的数字。
第3四分位数与第1四分位数的差距又称四分位距(InterQuartile Range,IQR)
ary = np.array([1,1,1,2,2,2,2,2,2,2,3,3,3,3,3,3,3,3,3,3,3,3,4,4,4,4,5,5,5])
s = pd.Series(ary)
s.quantile([.0, .25, .5, .75, 1.])
标准差
样本(sample):
S
=
[
s
1
,
s
2
,
s
3
,
.
.
.
,
s
n
]
S = [s_1, s_2, s_3, ..., s_n]
S=[s1,s2,s3,...,sn]
平均值:
m
=
s
1
+
s
2
+
s
3
+
.
.
.
+
s
n
n
m = \frac{s_1 + s_2 + s_3 + ... + s_n}{n}
m=ns1+s2+s3+...+sn
离差(deviation):表示某组数据距离某个中心点的偏离程度
D
=
[
d
1
,
d
2
,
d
3
,
.
.
.
,
d
n
]
d
i
=
S
i
−
m
D = [d_1, d_2, d_3, ..., d_n]\\ d_i = S_i-m
D=[d1,d2,d3,...,dn]di=Si−m
离差方:
Q
=
[
q
1
,
q
2
,
q
3
,
.
.
.
,
q
n
]
q
i
=
d
i
2
Q = [q_1, q_2, q_3, ..., q_n]\\ q_i=d_i^2
Q=[q1,q2,q3,...,qn]qi=di2
总体方差(variance):
v
=
(
q
1
+
q
2
+
q
3
+
.
.
.
+
q
n
)
n
v = \frac{(q_1+q_2+q_3 + ... + q_n)}{n}
v=n(q1+q2+q3+...+qn)
总体标准差(standard deviation):
s
=
v
s = \sqrt{v}
s=v
样本方差:
v
′
=
(
q
1
+
q
2
+
q
3
+
.
.
.
+
q
n
)
n
−
1
v' = \frac{(q_1+q_2+q_3 + ... + q_n)}{n-1}
v′=n−1(q1+q2+q3+...+qn)
其中,n-1称之为“贝塞尔校正”,这是因为抽取样本时候,采集的样本主要是落在中心值附近,那么通过这些样本计算的方差会小于等于对总体数据集方差的无偏估计值。为了能弥补这方面的缺陷,那么我们把公式的n改为n-1,以此来提高方差的数值。称为贝塞尔校正系数。
样本标准差:
s
′
=
v
′
s' = \sqrt{v'}
s′=v′
案例: 根据标准差理论,针对评分数据进行方差分析:
ratings.std(axis=0)
宏观数值统计
ratings.describe()
协方差、相关矩阵、相关系数
通过两组统计数据计算而得的协方差可以评估这两组统计数据的相似程度(相关性)。
样本:
A = [a1, a2, ..., an]
B = [b1, b2, ..., bn]
平均值:
ave_a = (a1 + a2 +...+ an)/n
ave_b = (b1 + b2 +...+ bn)/n
离差(用样本中的每一个元素减去平均数,求得数据的误差程度):
dev_a = [a1, a2, ..., an] - ave_a
dev_b = [b1, b2, ..., bn] - ave_b
协方差
协方差可以简单反映两组统计样本的相关性,值为正,则为正相关;值为负,则为负相关,绝对值越大相关性越强。
cov_ab = mean(dev_a x dev_b)
cov_ba = mean(dev_b x dev_a)
案例:计算两组股票数据的协方差,得出分析结论。
bhp = pd.read_csv('../data/bhp.csv', header=None, usecols=[6], names=['closing'])
vale = pd.read_csv('../data/vale.csv', header=None, usecols=[6], names=['closing'])
#平均值
ave_bhp = np.mean(bhp)
ave_vale = np.mean(vale)
#离差
dev_bhp = bhp - ave_bhp
dev_vale = vale - ave_vale
#协方差
cov_ab = np.mean(dev_bhp*dev_vale)
cov_ab
相关系数
协方差除去两组统计样本标准差的乘积是一个[-1, 1]之间的数。该结果称为统计样本的相关系数。
# a组样本 与 b组样本做对照后的相关系数
cov_ab/(std_a x std_b)
# b组样本 与 a组样本做对照后的相关系数
cov_ba/(std_b x std_a)
# a样本与a样本作对照 b样本与b样本做对照 二者必然相等
cov_ab/(std_a x std_b)=cov_ba/(std_b x std_a)
通过相关系数可以分析两组数据的相关性:
若相关系数越接近于0,越表示两组样本越不相关。
若相关系数越接近于1,越表示两组样本正相关。
若相关系数越接近于-1,越表示两组样本负相关。
案例:输出案例中两组数据的相关系数。
#相关系数: 协方差 /两组样本标准差之积
print('相关系数:', cov_ab/(np.std(a)*np.std(b)), cov_ba/(np.std(a)*np.std(b)))
# 直接返回相关系数
np.corrcoef(bhp,vale)
相关矩阵
[
v
a
r
_
a
s
t
d
_
a
×
s
t
d
_
a
c
o
v
_
a
b
s
t
d
_
a
×
s
t
d
_
b
c
o
v
_
b
a
s
t
d
_
b
×
s
t
d
_
a
v
a
r
_
b
s
t
d
_
b
×
s
t
d
_
b
]
\left[ \begin{array}{c} \frac{var\_a}{std\_a \times std\_a} & \frac{cov\_ab}{std\_a \times std\_b} \\ \frac{cov\_ba}{std\_b \times std\_a} & \frac{var\_b}{std\_b \times std\_b}\\ \end{array} \right ]
[std_a×std_avar_astd_b×std_acov_bastd_a×std_bcov_abstd_b×std_bvar_b]
矩阵正对角线上的值都为1。(同组样本自己相比绝对正相关)
[
1
c
o
v
_
a
b
s
t
d
_
a
×
s
t
d
_
b
c
o
v
_
b
a
s
t
d
_
b
×
s
t
d
_
a
1
]
\left[ \begin{array}{ccc} 1 & \frac{cov\_ab}{std\_a \times std\_b} \\ \frac{cov\_ba}{std\_b \times std\_a} & 1\\ \end{array} \right ]
[1std_b×std_acov_bastd_a×std_bcov_ab1]
numpy与pandas提供了求得相关矩阵与协方差矩阵的API:
# 相关矩阵
a = [5, 3, 5, 3, 1]
b = [4, 2, 3, 4, 2]
np.corrcoef(a, b)
dataFrame.corr()
# 协方差矩阵
# [[aa的协方差,ab的协方差], [ba的协方差, bb的协方差]]
np.cov(a, b)
dataFrame.cov()
项目:保健品消费情况特征描述性统计分析
项目文件资源下载
在我的资源文件中下载:
https://download.csdn.net/download/yegeli/12562286
保健品.csv、保健品字段介绍.csv
import numpy as np
import pandas as pd
data = pd.read_csv('保健品.csv', engine='python')
# 拿到前20题的结果
sub_data = data.loc[:, :'q5_20']
sub_data.head()
q5_01 | q5_02 | q5_03 | q5_04 | q5_05 | q5_06 | q5_07 | q5_08 | q5_09 | q5_10 | q5_11 | q5_12 | q5_13 | q5_14 | q5_15 | q5_16 | q5_17 | q5_18 | q5_19 | q5_20 | |
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
0 | 3 | 3 | 4 | 5 | 5 | 5 | 4 | 5 | 3 | 4 | 4 | 4 | 3 | 4 | 5 | 5 | 2 | 3 | 4 | 4 |
1 | 5 | 4 | 5 | 5 | 5 | 5 | 5 | 4 | 4 | 4 | 4 | 3 | 4 | 4 | 5 | 5 | 5 | 4 | 4 | 5 |
2 | 5 | 5 | 5 | 5 | 1 | 1 | 4 | 1 | 1 | 1 | 5 | 1 | 1 | 5 | 5 | 1 | 1 | 5 | 1 | 1 |
3 | 3 | 5 | 5 | 1 | 1 | 1 | 4 | 5 | 4 | 4 | 4 | 2 | 3 | 4 | 3 | 4 | 4 | 1 | 1 | 5 |
4 | 5 | 4 | 2 | 2 | 3 | 4 | 4 | 3 | 4 | 3 | 2 | 5 | 3 | 2 | 3 | 4 | 3 | 4 | 5 | 3 |
q5_01 令面色红润
q5_02 使皮肤有光泽
q5_03 精神状态好
q5_04 去斑
q5_05 去痘
q5_06 去皱
q5_07 解决皮肤干燥
q5_08 调节内分泌
q5_09 延缓皮肤衰老
q5_10 去除疲劳
q5_11 提高睡眠质量
q5_12 消除黑眼圈
q5_13 通便润肠
q5_14 抗衰老
q5_15 提高免疫力
q5_16 应该对自己好点
q5_17 希望自己像模特一样
q5_18 同龄人都在服用
q5_19 年轻人对我说该服用
q5_20 女为悦己者容
q8 主要服用的产品
w1 婚姻
w2 教育
w6 个人收入
desc = sub_data.describe()
desc
q5_01 | q5_02 | q5_03 | q5_04 | q5_05 | q5_06 | q5_07 | q5_08 | q5_09 | q5_10 | q5_11 | q5_12 | q5_13 | q5_14 | q5_15 | q5_16 | q5_17 | q5_18 | q5_19 | q5_20 | |
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
count | 625.000000 | 625.000000 | 625.0000 | 625.000000 | 625.000000 | 625.000000 | 625.000000 | 625.000000 | 625.000000 | 625.000000 | 625.000000 | 625.000000 | 625.000000 | 625.00000 | 625.00000 | 625.000000 | 625.000000 | 625.000000 | 625.000000 | 625.000000 |
mean | 3.804800 | 3.932800 | 4.1552 | 3.305600 | 2.760000 | 3.276800 | 3.683200 | 3.643200 | 3.750400 | 3.900800 | 3.844800 | 3.139200 | 3.438400 | 3.66560 | 4.03200 | 3.868800 | 2.694400 | 3.036800 | 3.032000 | 3.275200 |
std | 1.288625 | 1.173408 | 1.0454 | 1.485308 | 1.561763 | 1.545835 | 1.353576 | 1.382951 | 1.371097 | 1.149031 | 1.290961 | 1.406766 | 1.413011 | 1.41144 | 1.18711 | 1.261639 | 1.559005 | 1.386839 | 1.358355 | 1.417985 |
min | 1.000000 | 1.000000 | 1.0000 | 1.000000 | 1.000000 | 1.000000 | 1.000000 | 1.000000 | 1.000000 | 1.000000 | 1.000000 | 1.000000 | 1.000000 | 1.00000 | 1.00000 | 1.000000 | 1.000000 | 1.000000 | 1.000000 | 1.000000 |
25% | 3.000000 | 3.000000 | 4.0000 | 2.000000 | 1.000000 | 2.000000 | 3.000000 | 3.000000 | 3.000000 | 3.000000 | 3.000000 | 2.000000 | 2.000000 | 3.00000 | 3.00000 | 3.000000 | 1.000000 | 2.000000 | 2.000000 | 2.000000 |
50% | 4.000000 | 4.000000 | 4.0000 | 4.000000 | 3.000000 | 4.000000 | 4.000000 | 4.000000 | 4.000000 | 4.000000 | 4.000000 | 3.000000 | 4.000000 | 4.00000 | 4.00000 | 4.000000 | 2.000000 | 3.000000 | 3.000000 | 3.000000 |
75% | 5.000000 | 5.000000 | 5.0000 | 5.000000 | 4.000000 | 5.000000 | 5.000000 | 5.000000 | 5.000000 | 5.000000 | 5.000000 | 4.000000 | 5.000000 | 5.00000 | 5.00000 | 5.000000 | 4.000000 | 4.000000 | 4.000000 | 5.000000 |
max | 5.000000 | 5.000000 | 5.0000 | 5.000000 | 5.000000 | 5.000000 | 5.000000 | 5.000000 | 5.000000 | 5.000000 | 5.000000 | 5.000000 | 5.000000 | 5.00000 | 5.00000 | 5.000000 | 5.000000 | 5.000000 | 5.000000 | 5.000000 |
相关性分析
corr = sub_data.corr()
corr[corr>0.4] = 999
corr[corr<=0.4] = 0
corr
q5_01 | q5_02 | q5_03 | q5_04 | q5_05 | q5_06 | q5_07 | q5_08 | q5_09 | q5_10 | q5_11 | q5_12 | q5_13 | q5_14 | q5_15 | q5_16 | q5_17 | q5_18 | q5_19 | q5_20 | |
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
q5_01 | 999.0 | 999.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 |
q5_02 | 999.0 | 999.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 |
q5_03 | 0.0 | 0.0 | 999.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 |
q5_04 | 0.0 | 0.0 | 0.0 | 999.0 | 0.0 | 999.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 |
q5_05 | 0.0 | 0.0 | 0.0 | 0.0 | 999.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 |
q5_06 | 0.0 | 0.0 | 0.0 | 999.0 | 0.0 | 999.0 | 999.0 | 0.0 | 999.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 |
q5_07 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 999.0 | 999.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 |
q5_08 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 999.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 |
q5_09 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 999.0 | 0.0 | 0.0 | 999.0 | 0.0 | 0.0 | 0.0 | 0.0 | 999.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 |
q5_10 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 999.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 |
q5_11 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 999.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 |
q5_12 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 999.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 |
q5_13 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 999.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 |
q5_14 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 999.0 | 0.0 | 0.0 | 0.0 | 0.0 | 999.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 |
q5_15 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 999.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 |
q5_16 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 999.0 | 0.0 | 0.0 | 0.0 | 0.0 |
q5_17 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 999.0 | 0.0 | 0.0 | 0.0 |
q5_18 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 999.0 | 999.0 | 0.0 |
q5_19 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 999.0 | 999.0 | 0.0 |
q5_20 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 999.0 |
通过相关性分析,发现某些字段之间有正相关关系,代表保健品解决的是同一种问题。可以把当前这20道题总结出几个主要方面(消费保健品的重要因素)便于后期分析:
- 改善精神状态
- 抗衰老
- 有益于身体健康
- 关注外界看法
分析市场中现有的保健品所关注的功效
mean_score = desc.loc['mean']
# 降序排列均值数组
mean_score = mean_score.sort_values(ascending=False)
# 整理结果
fields = pd.read_csv('保健品字段介绍.csv', engine='python',
header=None, names=['fid', 'effect', '_'],
usecols=['fid', 'effect'], index_col='fid',
encoding='gbk')
fields['mean_score'] = mean_score
# by:按照mean_score列进行降序排列
fields = fields.sort_values(by='mean_score', ascending=False)
fields
effect | mean_score | |
---|---|---|
fid | ||
q5_03 | 精神状态好 | 4.1552 |
q5_15 | 提高免疫力 | 4.0320 |
q5_02 | 使皮肤有光泽 | 3.9328 |
q5_10 | 去除疲劳 | 3.9008 |
q5_16 | 应该对自己好点 | 3.8688 |
q5_11 | 提高睡眠质量 | 3.8448 |
q5_01 | 令面色红润 | 3.8048 |
q5_09 | 延缓皮肤衰老 | 3.7504 |
q5_07 | 解决皮肤干燥 | 3.6832 |
q5_14 | 抗衰老 | 3.6656 |
q5_08 | 调节内分泌 | 3.6432 |
q5_13 | 通便润肠 | 3.4384 |
q5_04 | 去斑 | 3.3056 |
q5_06 | 去皱 | 3.2768 |
q5_20 | 女为悦己者容 | 3.2752 |
q5_12 | 消除黑眼圈 | 3.1392 |
q5_18 | 同龄人都在服用 | 3.0368 |
q5_19 | 年轻人对我说该服用 | 3.0320 |
q5_05 | 去痘 | 2.7600 |
q5_17 | 希望自己像模特一样 | 2.6944 |
q8 | 主要服用的产品 | NaN |
w1 | 婚姻 | NaN |
w2 | 教育 | NaN |
w6 | 个人收入 | NaN |
通过上表可得:多数产品在产品功效上更多关注改善用户的精神状态,其次抗衰老,再次为身体健康,最后为外界因素。
统计收集到的结果中每一种保健品的已婚未婚频数
# w1字段的频数
result = data['w1'].value_counts()
result / result.sum()
2 0.7248
1 0.2752
Name: w1, dtype: float64
收集到的数据中,已婚占比:72% 未婚占比:27%
统计每一种保健品的频数
products = {1:'太太**',2:'乌鸡**',3:'排毒**',4:'阿*',
5:'红桃*',6:'脑白*',7:'朵**',9:'其他'}
products = pd.Series(products)
r = data['q8'].value_counts()
# 把两个Series合并到一个DataFrame中
result = pd.DataFrame({'products':products, 'q8':r})
result.sort_values(by='q8', ascending=False)
products | q8 | |
---|---|---|
9 | 其他 | 282 |
3 | 排毒** | 83 |
1 | 太太** | 55 |
5 | 红桃* | 55 |
7 | 朵** | 55 |
4 | 阿* | 40 |
2 | 乌鸡** | 32 |
6 | 脑白* | 23 |
由结果可知,市场占有率最高的是“排毒”,第二梯队:“太太”、“红桃”、“朵”,针对当前这种情况,如果想要切入保健品市场,可以尽快抢占:“乌鸡”、“阿”等产品的市场占有率,进而慢慢蚕食第二梯队的市场。所以后续分析可以关注一下这几个品牌。
研究每个产品的功效的侧重点
# 研究每一个的产品 功效侧重点
result1 = pd.DataFrame([])
for k, v in products.items():
mask = data['q8']==k
result1[k] = sub_data[mask].mean()
result1
1 | 2 | 3 | 4 | 5 | 6 | 7 | 9 | |
---|---|---|---|---|---|---|---|---|
q5_01 | 4.181818 | 3.87500 | 3.855422 | 3.625 | 3.745455 | 3.565217 | 3.636364 | 3.797872 |
q5_02 | 4.218182 | 4.03125 | 3.915663 | 3.550 | 3.890909 | 3.652174 | 4.127273 | 3.918440 |
q5_03 | 4.018182 | 4.03125 | 4.216867 | 3.900 | 4.272727 | 3.913043 | 4.200000 | 4.202128 |
q5_04 | 3.509091 | 3.37500 | 3.457831 | 2.650 | 3.109091 | 3.478261 | 3.290909 | 3.333333 |
q5_05 | 2.563636 | 2.84375 | 3.108434 | 1.925 | 2.945455 | 2.869565 | 3.163636 | 2.680851 |
q5_06 | 3.727273 | 3.21875 | 3.253012 | 3.200 | 2.854545 | 3.478261 | 3.527273 | 3.230496 |
q5_07 | 3.872727 | 3.78125 | 3.843373 | 3.325 | 3.400000 | 3.782609 | 3.872727 | 3.648936 |
q5_08 | 3.818182 | 4.03125 | 3.867470 | 3.200 | 3.272727 | 3.521739 | 3.690909 | 3.634752 |
q5_09 | 3.963636 | 3.53125 | 3.795181 | 3.550 | 3.472727 | 3.478261 | 3.745455 | 3.826241 |
q5_10 | 3.636364 | 3.81250 | 3.771084 | 3.775 | 4.000000 | 3.173913 | 4.090909 | 4.021277 |
q5_11 | 3.890909 | 3.87500 | 3.530120 | 3.450 | 3.890909 | 4.130435 | 3.836364 | 3.950355 |
q5_12 | 3.218182 | 2.90625 | 3.192771 | 2.325 | 3.254545 | 3.608696 | 3.309091 | 3.156028 |
q5_13 | 3.327273 | 3.59375 | 3.759036 | 3.000 | 2.818182 | 3.217391 | 3.672727 | 3.503546 |
q5_14 | 3.781818 | 3.62500 | 3.614458 | 3.525 | 3.181818 | 3.347826 | 3.563636 | 3.822695 |
q5_15 | 3.836364 | 4.15625 | 4.024096 | 3.900 | 4.000000 | 3.782609 | 3.872727 | 4.134752 |
q5_16 | 3.800000 | 4.46875 | 3.626506 | 3.525 | 4.109091 | 3.391304 | 4.072727 | 3.886525 |
q5_17 | 2.927273 | 2.71875 | 2.746988 | 2.225 | 3.090909 | 2.217391 | 3.036364 | 2.592199 |
q5_18 | 3.145455 | 3.46875 | 3.108434 | 2.575 | 3.200000 | 2.826087 | 3.272727 | 2.950355 |
q5_19 | 3.290909 | 3.37500 | 2.963855 | 2.725 | 3.218182 | 2.869565 | 3.072727 | 2.975177 |
q5_20 | 3.509091 | 3.78125 | 3.626506 | 2.375 | 3.109091 | 2.826087 | 3.254545 | 3.269504 |
# 获取每一列的最大值的索引,可以理解为每个产品最注重的功效
result_idxmax = result1.idxmax()
result2 = pd.DataFrame(
{'products':products, 'idxmax': result_idxmax})
result2
idxmax | products | |
---|---|---|
1 | q5_02 | 太太** |
2 | q5_16 | 乌鸡** |
3 | q5_03 | 排毒** |
4 | q5_03 | 阿* |
5 | q5_03 | 红桃* |
6 | q5_11 | 脑白* |
7 | q5_03 | 朵** |
9 | q5_03 | 其他 |
# 迭代idxmax列,通过fid得到一组对应的功效字符串,追加到result2
def func(item):
return fields['effect'].loc[item]
result2['effect'] = result2['idxmax'].apply(func)
result2
idxmax | products | effect | |
---|---|---|---|
1 | q5_02 | 太太** | 使皮肤有光泽 |
2 | q5_16 | 乌鸡** | 应该对自己好点 |
3 | q5_03 | 排毒** | 精神状态好 |
4 | q5_03 | 阿* | 精神状态好 |
5 | q5_03 | 红桃* | 精神状态好 |
6 | q5_11 | 脑白* | 提高睡眠质量 |
7 | q5_03 | 朵** | 精神状态好 |
9 | q5_03 | 其他 | 精神状态好 |
由每个产品的功效侧重点可得:
若希望切入保健品市场,功效方面则优先保证改善用户的精神状态。而针对“乌鸡”、“阿”这些竞品,可以从广告投放,舆论扩散,产品口号等角度抢占他们的市场。
研究每个产品的用户群体,婚否字段分析
# w1字段的频数
result = data['w1'].value_counts()
result / result.sum()
2 0.7248
1 0.2752
Name: w1, dtype: float64
# 研究q8==k的用户群体
result3 = pd.DataFrame([])
for k, v in products.items():
mask = data['q8']==k
result3[k] = data[mask]['w1'].value_counts()
result3 = result3.T
result3.columns = ['married', 'not-married']
result3['product'] = products
result3['effect'] = result2['effect']
result3
married | not-married | product | effect | |
---|---|---|---|---|
1 | 50 | 5 | 太太** | 使皮肤有光泽 |
2 | 21 | 11 | 乌鸡** | 应该对自己好点 |
3 | 47 | 36 | 排毒** | 精神状态好 |
4 | 39 | 1 | 阿* | 精神状态好 |
5 | 24 | 31 | 红桃* | 精神状态好 |
6 | 13 | 10 | 脑白* | 提高睡眠质量 |
7 | 42 | 13 | 朵** | 精神状态好 |
9 | 217 | 65 | 其他 | 精神状态好 |
可知:“太太”、“阿”、“红桃”对婚姻属性比较敏感,前两者针对已婚女士,“红桃”针对未婚女士。已婚女士更关注保健品的护肤、抗衰老等功效,未婚女士更多要保持年轻精神状态。针对“乌鸡”、“阿”角度分析,可以更多关注已婚女士对保健品的需求,设计相关产品形象。
结论
- 多数产品在产品功效上更多关注改善用户的精神状态,其次抗衰老,再次为身体健康,最后为外界因素。
- 如果想要切入保健品市场,可以尽快抢占:“乌鸡”、“阿”等产品的市场占有率,进而慢慢蚕食第二梯队的市场。所以后续分析可以关注一下这几个品牌。
- 若希望切入保健品市场,功效方面则优先保证改善用户的精神状态。而针对“乌鸡”、“阿”这些竞品,可以从广告投放,舆论扩散,产品口号等角度抢占他们的市场。
- 已婚女士更关注保健品的护肤、抗衰老等功效,未婚女士更多要保持年轻精神状态。针对“乌鸡”、“阿”角度分析,可以更多关注已婚女士对保健品的需求,设计相关产品形象。
代码总结
import numpy as np
import pandas as pd
ratings = pd.read_json('../../data/ratings.json')
ratings
John Carson | Michelle Peterson | William Reynolds | Jillian Hobart | Melissa Jones | Alex Roberts | Michael Henry | |
---|---|---|---|---|---|---|---|
Inception | 2.5 | 3.0 | 2.5 | NaN | 3 | 3.0 | NaN |
Pulp Fiction | 3.5 | 3.5 | 3.0 | 3.5 | 4 | 4.0 | 4.5 |
Anger Management | 3.0 | 1.5 | NaN | 3.0 | 2 | NaN | NaN |
Fracture | 3.5 | 5.0 | 3.5 | 4.0 | 3 | 5.0 | 4.0 |
Serendipity | 2.5 | 3.5 | NaN | 2.5 | 2 | 3.5 | 1.0 |
Jerry Maguire | 3.0 | 3.0 | 4.0 | 4.5 | 3 | 3.0 | NaN |
m = ratings.loc['Inception'].mean()
m = ratings.mean()
m = ratings.mean(axis=1)
m
Inception 2.800000
Pulp Fiction 3.714286
Anger Management 2.375000
Fracture 4.000000
Serendipity 2.500000
Jerry Maguire 3.416667
dtype: float64
scores = ratings.loc['Fracture']
weights = [3, 5, 5, 3, 1, 1, 1]
s = np.average(scores, weights=weights)
s
4.052631578947368
最值
np.max(ratings['Alex Roberts']), np.min(ratings['Alex Roberts'])
(5.0, 3.0)
ratings.max(axis=1)
Inception 3.0
Pulp Fiction 4.5
Anger Management 3.0
Fracture 5.0
Serendipity 3.5
Jerry Maguire 4.5
dtype: float64
ratings.idxmax(axis=1)
Inception Michelle Peterson
Pulp Fiction Michael Henry
Anger Management John Carson
Fracture Michelle Peterson
Serendipity Michelle Peterson
Jerry Maguire Jillian Hobart
dtype: object
ratings.idxmin()
John Carson Inception
Michelle Peterson Anger Management
William Reynolds Inception
Jillian Hobart Serendipity
Melissa Jones Anger Management
Alex Roberts Inception
Michael Henry Serendipity
dtype: object
中位数
np.median(ratings.loc['Fracture'])
4.0
ratings.median()
John Carson 3.00
Michelle Peterson 3.25
William Reynolds 3.25
Jillian Hobart 3.50
Melissa Jones 3.00
Alex Roberts 3.50
Michael Henry 4.00
dtype: float64
ratings
John Carson | Michelle Peterson | William Reynolds | Jillian Hobart | Melissa Jones | Alex Roberts | Michael Henry | |
---|---|---|---|---|---|---|---|
Inception | 2.5 | 3.0 | 2.5 | NaN | 3 | 3.0 | NaN |
Pulp Fiction | 3.5 | 3.5 | 3.0 | 3.5 | 4 | 4.0 | 4.5 |
Anger Management | 3.0 | 1.5 | NaN | 3.0 | 2 | NaN | NaN |
Fracture | 3.5 | 5.0 | 3.5 | 4.0 | 3 | 5.0 | 4.0 |
Serendipity | 2.5 | 3.5 | NaN | 2.5 | 2 | 3.5 | 1.0 |
Jerry Maguire | 3.0 | 3.0 | 4.0 | 4.5 | 3 | 3.0 | NaN |
频数与众数
cars = np.array(['bmw', 'bmw', 'bz', 'bz', 'audi', 'bz', 'bmw'])
cars = pd.Series(cars)
cars.value_counts()
bmw 3
bz 3
audi 1
dtype: int64
cars.mode()
0 bmw
1 bz
dtype: object
四分位数
data = pd.read_csv('CustomerSurvival.csv', header=None)
data
extra_time = data[2]
extra_time.quantile([.0, .25, .5, .75, 1.])
0.00 -2828.33
0.25 -126.67
0.50 13.50
0.75 338.66
1.00 4314.00
Name: 2, dtype: float64
方差与标准差
# ddof=1: 贝塞尔校正系数
np.std(ratings['John Carson'], ddof=1), \
np.std(ratings['Michelle Peterson'])
(0.4472135954999579, 1.0307764064044151)
ratings.std()
John Carson 0.447214
Michelle Peterson 1.129159
William Reynolds 0.645497
Jillian Hobart 0.790569
Melissa Jones 0.752773
Alex Roberts 0.836660
Michael Henry 1.892969
dtype: float64
ratings.describe()
John Carson | Michelle Peterson | William Reynolds | Jillian Hobart | Melissa Jones | Alex Roberts | Michael Henry | |
---|---|---|---|---|---|---|---|
count | 6.000000 | 6.000000 | 4.000000 | 5.000000 | 6.000000 | 5.00000 | 3.000000 |
mean | 3.000000 | 3.250000 | 3.250000 | 3.500000 | 2.833333 | 3.70000 | 3.166667 |
std | 0.447214 | 1.129159 | 0.645497 | 0.790569 | 0.752773 | 0.83666 | 1.892969 |
min | 2.500000 | 1.500000 | 2.500000 | 2.500000 | 2.000000 | 3.00000 | 1.000000 |
25% | 2.625000 | 3.000000 | 2.875000 | 3.000000 | 2.250000 | 3.00000 | 2.500000 |
50% | 3.000000 | 3.250000 | 3.250000 | 3.500000 | 3.000000 | 3.50000 | 4.000000 |
75% | 3.375000 | 3.500000 | 3.625000 | 4.000000 | 3.000000 | 4.00000 | 4.250000 |
max | 3.500000 | 5.000000 | 4.000000 | 4.500000 | 4.000000 | 5.00000 | 4.500000 |
data.describe()
0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | |
---|---|---|---|---|---|---|---|---|---|---|
count | 4975.000000 | 4975.000000 | 4975.000000 | 4975.000000 | 4975.000000 | 4975.000000 | 4975.000000 | 4975.000000 | 4975.000000 | 4975.000000 |
mean | 2488.000000 | 1.057688 | 258.520034 | -71.580422 | 0.021307 | 0.245226 | 0.047437 | 0.227337 | 14.774271 | 0.782714 |
std | 1436.303125 | 0.258527 | 723.057213 | 275.557448 | 0.144419 | 0.430264 | 0.278143 | 0.419154 | 6.534273 | 0.412441 |
min | 1.000000 | 1.000000 | -2828.330000 | -2189.880000 | 0.000000 | 0.000000 | 0.000000 | 0.000000 | 1.000000 | 0.000000 |
25% | 1244.500000 | 1.000000 | -126.670000 | -74.290000 | 0.000000 | 0.000000 | 0.000000 | 0.000000 | 13.000000 | 1.000000 |
50% | 2488.000000 | 1.000000 | 13.500000 | -59.650000 | 0.000000 | 0.000000 | 0.000000 | 0.000000 | 13.000000 | 1.000000 |
75% | 3731.500000 | 1.000000 | 338.660000 | -25.795000 | 0.000000 | 0.000000 | 0.000000 | 0.000000 | 19.000000 | 1.000000 |
max | 4975.000000 | 3.000000 | 4314.000000 | 2568.700000 | 1.000000 | 1.000000 | 2.000000 | 1.000000 | 25.000000 | 1.000000 |
协方差、相关矩阵、相关系数
A = ratings['John Carson']
B = ratings['Melissa Jones']
# 求两组数据的均值
mean_a = A.mean()
mean_b = B.mean()
# 求离差
dev_a = A - mean_a
dev_b = B - mean_b
# 求协方差
cov_ab = np.mean(dev_a * dev_b)
cov_ab
0.16666666666666666
# 相关系数 协方差/两组样本标准差之积
coef = cov_ab / (np.std(A) * np.std(B))
coef
0.5940885257860046
# np.corrcoef() 返回相关系数矩阵
np.corrcoef(A, B)
C = ratings['Michelle Peterson']
np.corrcoef([A, B, C])
array([[1. , 0.59408853, 0.39605902],
[0.59408853, 1. , 0.41176471],
[0.39605902, 0.41176471, 1. ]])
ratings.corr()
John Carson | Michelle Peterson | William Reynolds | Jillian Hobart | Melissa Jones | Alex Roberts | Michael Henry | |
---|---|---|---|---|---|---|---|
John Carson | 1.000000 | 0.396059 | 0.404520 | 0.566947 | 0.594089 | 0.747018 | 0.991241 |
Michelle Peterson | 0.396059 | 1.000000 | 0.204598 | 0.314970 | 0.411765 | 0.963796 | 0.381246 |
William Reynolds | 0.404520 | 0.204598 | 1.000000 | 1.000000 | -0.258199 | 0.134840 | -1.000000 |
Jillian Hobart | 0.566947 | 0.314970 | 1.000000 | 1.000000 | 0.566947 | 0.028571 | 0.893405 |
Melissa Jones | 0.594089 | 0.411765 | -0.258199 | 0.566947 | 1.000000 | 0.211289 | 0.924473 |
Alex Roberts | 0.747018 | 0.963796 | 0.134840 | 0.028571 | 0.211289 | 1.000000 | 0.662849 |
Michael Henry | 0.991241 | 0.381246 | -1.000000 | 0.893405 | 0.924473 | 0.662849 | 1.000000 |
ratings
John Carson | Michelle Peterson | William Reynolds | Jillian Hobart | Melissa Jones | Alex Roberts | Michael Henry | |
---|---|---|---|---|---|---|---|
Inception | 2.5 | 3.0 | 2.5 | NaN | 3 | 3.0 | NaN |
Pulp Fiction | 3.5 | 3.5 | 3.0 | 3.5 | 4 | 4.0 | 4.5 |
Anger Management | 3.0 | 1.5 | NaN | 3.0 | 2 | NaN | NaN |
Fracture | 3.5 | 5.0 | 3.5 | 4.0 | 3 | 5.0 | 4.0 |
Serendipity | 2.5 | 3.5 | NaN | 2.5 | 2 | 3.5 | 1.0 |
Jerry Maguire | 3.0 | 3.0 | 4.0 | 4.5 | 3 | 3.0 | NaN |