利用Pandas进行数据预处理的一个简单小案例

待处理数据(一部分)

原始数据为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: 6Unnamed: 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字段:

# 加入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

猜你喜欢

转载自blog.csdn.net/qq_45220637/article/details/107571943