原始数据为30w行,以下为在原始数据中抽取的四个比较有代表性的数据作为参考使用。
// 以下为待处理数据的一部分,供参考用
user_id item_id behavior_type user_geohash item_category time
10001082 285259775 1 97lk14c 4076 2014-12-08 18
10001082 53616768 4 9762 2014-12-02 15
100029775 128989040 2 9t4qcbq 5232 2014-12-17 17
100029775 222229697 3 3628 2014-12-12 15
字段 | 说明 |
---|---|
user_id | 用户ID |
item_id | 商品ID |
behavior_type | 1.浏览 2.收藏 3.加购物车 4.购买 |
user_geohash | 购买地理位置 |
item_category | 品类ID(商品所属的品类) |
time | 时间 |
(1)删除文件第一行字段
(2)删除读取的文件的第四个字段
(3)增加id字段,从1开始顺序递增
(3)保留完整的时间格式,2014-12-12,删除每行时间末尾的空格和18。
(4)读取的文件每行随机增加省份字段。
(5)生成新文件:small_user_out.csv,查看文件编码
(6)转换预处理生成文件small_user_out.csv的文件编码为utf8,保证在hive数据仓库里可以中文显示。
字段 | 说明 |
---|---|
id | 从1开始顺序递增 |
user_id | 用户ID |
item_id | 商品ID |
behavior_type | 1.浏览 2.收藏 3.加购物车 4.购买 |
item_category | 品类ID(商品所属的品类) |
time | 时间(处理过的) |
province | 省份(随机生成具体省份) |
使用pandas进行数据预处理。
从处理要求来看,删除第一行可以等导出文件的时候不包含头部就可以解决。原始数据文件说明有6个字段,实际还有两个空字段为Unnamed: 6和Unnamed: 7字段,即实际查看到的数据为:
// 实际查看到的数据
user_id item_id behavior_type user_geohash item_category time Unnamed: 6 Unnamed: 7
10001082 285259775 1 97lk14c 4076 2014-12-08 18
10001082 53616768 4 9762 2014-12-02 15
100029775 128989040 2 9t4qcbq 5232 2014-12-17 17
100029775 222229697 3 3628 2014-12-12 15
而我们处理完的数据字段说明里并没有这两个字段。所以,我们在删除字段时需要把这两个字段也删除掉。修改时间格式,我们可以看到原有的时间格式时间和日期中间有“ ”隔开,因此我们可以用分割字符串的方式来修改数据。加入id字段我们可以先获取表的长度,然后根据长度生成一个从1开始的列表,插入一个新字段即可。读取的文件每行随机增加省份字段,我这里用的方法是自己建一个包含各省的列表,获取原始数据的行数,再建一个新的空列表,随机选择一个省份插入该空列表,进行和行数相同的次数后根据此时的列表生成新字段。最后数据处理完成,导出文件。
# 读取文件
fpath = ("原始数据文件地址")
df = pd.read_csv(fpath,low_memory=False)
pandas在读取的时候可能把同一列数据中相同的数值识别为不同的类型,因此可能会报错mixed types,所以我们在这里设置low_memory的参数为False或者直接定义每一列的数据类型可以避免这个问题,我这里是将low_memory的参数设置为False。使用low_memory=False的原理是,pandas会一次将所有数据读取完,只对数据类型进行一次猜测 ,但是这种方法如果文件过大可能会造成内存溢出。
# 删除第四个字段和后两个字段
df = df.drop(['user_geohash','Unnamed: 6','Unnamed: 7'],axis=1)
这里没什么好解释的,就是axis=1,指定删除列。
# 加入id字段
n = len(df)+1
n_list = range(1,n)
df.insert(0,'id',n_list)
用n接收得到的长度信息,这里使用插入可以指定插入id字段的位置。
# 修改分割时间字段
df['time'] = df['time'].str.split(' ',expand=True)[0]
添加一个参数expand=True,将列表分开,得到两列,然后右边的[0]选定生成两列里的第一列。
# 增加随机省份字段
print(df.shape[0])
city_list = ['北京','天津','河北','山西','内蒙古','辽宁','吉林','黑龙江','上海','江苏',
'浙江','安徽','福建','江西','山东','河南','湖北','湖南','广东','广西',
'海南','重庆','四川','贵州','云南','西藏', '陕西','甘肃','青海','宁夏',
'新疆','香港','澳门','台湾']
li = []
for i in range(df.shape[0]):
city = random.choice(city_list)
li.extend([city])
print(len(li))
df['province']= li
这里没有什么特别说明的地方。
需要处理的都已经处理完。我们可以执行print(df.head())查看一下结果是否正确。
tpath = ('导出路径')
df.to_csv(path_or_buf=tpath,header = False,index = False,encoding="utf-8-sig")
header = False index = False encoding=“utf-8-sig” 不导出index和columns,且编码格式为utf-8。
最开始我编码写的是encoding=“utf-8”发现导出的文件用excel打开中文是乱码,之后百度发现是没有BOM头的原因,解决方法就是把utf-8改为utf-8-sig。excel可以试别带有BOM头的utf-8,不能试别没有BOM头的,因此使用utf-8-sig用excel打开就不会有乱码了!实际我们数据预处理后的数据分析阶段并不是用excel,所以就算excel里是乱码,但它仍然是utf-8编码,后边的数据分析可以照常使用。
最后,如果你想尝试这个案例可以去我的网盘下载原始数据文件。
链接:https://pan.baidu.com/s/1-KS9L91o4Q8FEJeV8D9Lyg
提取码:irli