数据预处理

1. 去除不需要的数据

目标是:一个用户,后面全是用户的特征

  • 列数据中 Null 数据 > 80% 所有数据 isnull().sum()
  • 列数据中一样的数据 > 80%所有数据 value_counts()
  • 表示同一个意思的字段,只需要保留一个:如用户名、用户账号、支付账号、收货人姓名
  • 根据场景分析不需要的字段:如买家应付货款、应付邮费等

2. 只获取指定的列数据

1
2
df_order.ix[:, '订单编号', '买家会员名', '买家实际支付金额', '收货地址', '种类', '数量', '退款金额']
# ix是loc与iloc的合集,其中loc是按照列名来取数据,iloc是按照列的index来取数据

或者

1
df_order[['订单编号', '买家会员名', '买家实际支付金额', '收货地址', '种类', '数量', '退款金额']]

3. 对数据进行格式化

1
df_order['收货地址'] = df_order['收货地址'].apply(lambda x:x.split()[0])

4. 按照某列数据给整行数据打tag

1
2
3
4
5
6
7
8
9
def add_tag(info):
if '月' in info:
tag = '婴儿|'
if '':
tag = '幼儿|'
if:
tag = '学生|'
return tag[:-1]
attrs['tag'] = attrs['适用年龄'].apply(add_tag)

5. 数据合并

1
pd.merge(items, attrs, on='标题', how='inner')

6. 对每个用户进行分组汇总

1
2
3
order_tag['购买次数'] = 1
test2 = order_tag.groupby(['买家会员名', 'tag2']).count()
test2.unstack('tag2').fillna(0) # unstack将会把索引数据中的一列转为列名

7. 对重复的数据取平均值

1
2
res1 = res1.groupby(['会员', '地址']).mean()
res1.reset_index(inplace=True)

8. 将字符串转为数值的方法有两种:

  1. 用数值表示具体值,如:好、一般、差就用相关数值表示
  2. unstack将它转为column,或者get_dummies方法将非数值型转为column
1
2
pd.get_dummies?
result2= pd.get_dummies(res1) ##只会对非数值型有效

最后得到的数据:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
       买家实际支付金额  宝贝种类  宝贝总数量  退款金额  收货地址_上海  收货地址_云南省  收货地址_内蒙古自治区  收货地址_北京  \
买家会员名
409 35.31 8 11 0.0 0 0 0 0
2270 13.70 1 3 0.0 0 0 0 0
1908 55.09 7 7 0.0 0 0 0 0
1727 62.72 11 14 0.0 1 0 0 0
1976 18.80 1 2 0.0 0 1 0 0

收货地址_吉林省 收货地址_四川省 ... 收货地址_湖北省 收货地址_湖南省 收货地址_甘肃省 收货地址_福建省 \
买家会员名 ...
409 0 0 ... 0 0 0 0
2270 0 0 ... 0 0 0 0
1908 0 0 ... 0 0 0 0
1727 0 0 ... 0 0 0 0
1976 0 0 ... 0 0 0 0

收货地址_贵州省 收货地址_辽宁省 收货地址_重庆 收货地址_陕西省 收货地址_青海省 收货地址_黑龙江省
买家会员名
409 0 0 0 0 0 0
2270 0 0 0 0 0 0
1908 0 0 0 0 0 0
1727 0 0 0 0 0 0
1976 0 0 0 0 0 0

基于用户聚类

目标:对用户进行标记分类

1. 数据标准化

1
2
3
4
5
from sklearn.preprocessing import MinMaxScaler
data = order_df.ix[:,1:].values #去掉第一列数据,也就是用户id
mms=MinMaxScaler()
data_nore = mms.fit_transform(data)
print(data_nore)

2. 聚类

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
- 手肘法
from sklearn.cluster import KMeans
from matplotlib import pyplot as plt
sse = []
for k in range(1,15):
km = KMeans(n_clusters=k)
km.fit(data_nore)
sse.append(km.inertia_)
x = range(1, 15)
y = sse
plt.plot(x,y)
plt.show()

- 轮廓法
from sklearn.metrics import silhouette_score
score = []
for k in range(2, 15):
km=KMeans(n_clusters=k)
res_km = km.fit(data_nore)
score.append(silhouette_score(data_nore, res_km.labels_))
plt.plot(range(2, 15), score, marker='o')

#根据上面的值取得最优n_clusters值,例如为8
from sklearn.cluster import KMeans
km=KMeans(n_clusters=8)
res_km = km.fit(data_nore)
km.labels_ # 这个就是聚类结果,也是最终需要的结果

3. 将类别添加到分析数据中

1
result2['类别'] = km.labels_ #对原始用户进行类别标记

基于用户聚类进行推荐

目标:向用户推荐产品

同一类群中,大多数人喜欢的商品,用户也喜欢

1
2
3
4
order_df['商品购买次数'] = 1
data = order_df.groupby(['类别','商品'].count()) #不同类别人对商品的关注程度
data.reset_index(inplace=True)
print(data.ix[:, ['类别','商品', '商品购买次数']]) #得到类别->商品->购买次数

推荐给用户同一个类别,而没有购买过的商品,按照购买次数排序推荐。

基础知识

pandas.DataFrame基本方法

1
2
3
4
5
6
7
8
df.info() #查看数据信息
df.shape #获得数据行列数
del(df['a']) #删除某列数据
df['col'].values #查看数据
df.columns #查看列名
df.reset_index(inplace=True) #重置索引
df.index = df['index'] #创建索引
df = df.set_index('index') #将某列设置为索引

df合并

1
merged_df = left_df.merge(right_df, how="left", left_on=u'主机配置', right_on=u'主机说明')

根据某条数据的属性添加新的数据列

1
2
df['b'] = 0
df['b'][df['a']==1] = 8 ##注意先选完整的列,再过滤才能赋值

读取文件时,默认是utf8格式,也可以指定编码

常见的编码方式有:ascii/utf8/unicode/utf-16/gb2312/gbk/gb18030

1
pd.read_csv('file_path.csv', encoding='gb2312')

将一列数据转为多列数据

1
2
3
4
5
6
7
8
9
df = pd.DataFrame([{"a": 1, "name":"1|2|4"}, {"a": 2, "name":"1|5|9"}])
df[["b", "c", "d"]] = df['name'].str.split('|', expand=True) # 多名字分列
# 或者
df = df.join(df['name'].str.split('|', expand=True))

result:
a name b c d
0 1 1|2|4 1 2 4
1 2 1|5|9 1 5 9

将DataFrame中的tuple分割成数据框的多列

1
2
3
4
5
6
7
8
9
df = pd.DataFrame({'a':[1,2], 'b':[(1,2), (3,4)]})
df[['b1', 'b2']] = df['b'].apply(pd.Series)
# 或者
df = df.join(df['b'].apply(pd.Series))

result:
a b 0 1
0 1 (1, 2) 1 2
1 2 (3, 4) 3 4

stack与unstack使用说明:python pandas stack和unstack函数

利用当前数据的多列数据得到新的数据列

1
2
3
4
5
df['new_column'] = df.apply(lambda row: row['column1'] * row['column2'], axis=1)
# 或者
df['new_column'] = df['column1'] * df['column2']
# 或者
df.ix[:, 'new_column'] = df['column1'] * df['column2']

得到类型中有关系数据库的数据

1
df[df[u'类型'].str.contains(u'关系数据库')]

apply函数返回多列数据

1
2
3
4
5
6
7
8
9
10
11
def parse(item):
return pd.Series([item*2, item*4])

a = pd.DataFrame({'a': [1, 2, 3], 'b': [4, 5, 6]})
a[['2倍', '4倍']] = a['a'].apply(parse)

result:
a b 24
0 1 4 2 4
1 2 5 4 8
2 3 6 6 12

过滤逻辑类型

np.logical_and

1
data = df[np.logical_and(df['col1'].notnull(), df['col1'].str.contains('item'))]

更改列名

1
data = df.rename(columns={'col1': u'列1', 'col2': u'列2'})

将数据转化为常用类型

1
col1_data = df['col1'].tolist()