python微专业-数据分析师


 一、数据清洗入库体验

1、常见文件读写方式参考随笔:https://www.cnblogs.com/Eric15/p/10042342.html

2、python系统模块 - os模块介绍

 os 模块:提供了非常丰富的方法用来处理文件和目录

import os

print(os.name)  # 输出字符串指示正在使用的平台。如果是window 则输出'nt',如果是Linux/Unix用户,则输出'posix'

print(os.getcwd())  # 返回当前工作目录,即当前Python脚本工作的目录路径

print(os.listdir())        # 返回当前工作目录下的所有文件和目录名

os.chdir("C:\users\")    # 切换到目标路径下

os.path.split('C:\\Users\\Hjx\\Desktop\\text.txt')    # 将目录路径和文件名分开,返回一个元组:('C:\\Users\\Hjx\\Desktop', 'text.txt')

os.remove("text2.txt")        # 删除文件

os.path.exists('C:\\Users\\Hjx\\Desktop\\heheh.txt')        # 用于检验给出的路径是否存在

 

3、绝对路径与相对路径

os.chdir('C:\\Users\\Hjx\\Desktop\\' )    # 绝对路径
f2 = open('text.txt','r')                # 相对路径
print(f2.read())
# 上述中,通过chdir申明了目录之后,接着可以直接给文件名 → 相对路径

 

 数据清洗及存取demo:

# demo1:  商铺数据加载及存储

要求:
1、成功读取“商铺数据.csv”文件
2、解析数据,存成列表字典格式:[{'var1':value1,'var2':value2,'var3':values,...},...,{}]
3、数据清洗:
① comment,price两个字段清洗成数字
② 清除字段缺失的数据
③ commentlist拆分成三个字段,并且清洗成数字
4、结果存为.pkl文件

  商铺数据.csv:

  

 代码实现:

import pickle

def fcm(s):
    # 清洗comment(评论数)数据,并转换成int类型。  eg: "988                    条点评"
    if "" in s:
        return int(s.split(" ")[0])
    else:
        return "缺失数据"

def fpr(s):
    # 清洗price(价格)数据,并转换成float类型。  eg:"人均                                        ¥81"
    if "" in s:
        return float(s.split("")[-1])
    else:
        return "缺失数据"

def fcl(s):
    # commentlist清洗函数:用空格分段,分别清洗出质量、环境及服务数据,并转化为浮点型。  eg:"口味7.0                                环境7.0                                服务7.0"
    if " " in s:
        commentlist = s.split("                                ")
        quality = float(commentlist[0][2:])
        environment = float(commentlist[1][2:])
        service = float(commentlist[2][2:-1])
        return [quality,environment,service]
    else:
        return "缺失数据"

f = open(r"C:\Users\Administrator\Desktop\商铺数据.csv", "r", encoding="utf8")
data_list = []
n =0
for i in f.readlines()[1:]:
    data = i.split(",")
    # print(i.split(","))        # 根据","分割,返回列表数据
    classify = data[0]
    name = data[1]
    comment_count = fcm(data[2])
    star = data[3]
    price = fpr(data[4])
    address = data[5]
    commentlist = fcl(data[6])
    if "缺失数据" in commentlist:
        quality = commentlist
    else:
        quality, enviroment, service = fcl(data[6])

    if "缺失数据" not in [comment_count, price, quality]:        # 判断每条数据中是否存在缺失数据,如有则过滤
        n += 1             # 用于计数
        data_re = [
            ["classify",classify],
            ["name",name],
            ["comment_count",comment_count],
            ["star",star],
            ["price",price],
            ["address",address],
            ["quality",quality],
            ["enviroment",enviroment],
            ["service",service]
        ]
        data_list.append(dict(data_re))            # 生成字典,并将数据追加到列表data_list 中

        print("\n成功加载%i条数据"%n)

f.close()
print(data_list)
print("\n数据加载完毕,总共加载了%i条数据"%n)


# 将数据存储到pkl文件中:
f_pic = open(r"C:\Users\Administrator\Desktop\data.pkl", "wb")
pickle.dump(data_list, f_pic)
f_pic.close()
print("数据存储成功!")

# 读取data.pkl文件
f_pic = open(r"C:\Users\Administrator\Desktop\data.pkl", "rb")
data = pickle.load(f_pic)
f_pic.close()
print("数据加载完毕,如下所示:")
print(data)

 


二、数据分析核心技术

1. numpy 介绍

 numpy学习参考随笔:https://www.cnblogs.com/Eric15/p/10021362.html

 numpy 数组是一个多维数组对象,称为ndarray,其由两部分组成:

 ①. 实际的数据

 ②. 描述这些数据的元数据

1)创建数组的方式

 1.1)array() 函数,括号内可以是列表、元组、数组、生成器等

ar1 = np.array(range(10))   # 整型
ar2 = np.array([1,2,3.14,4,5])   # 浮点型
ar3 = np.array([[1,2,3],('a','b','c')])   # 二维数组:嵌套序列(列表,元祖均可)
ar4 = np.array([[1,2,3],('a','b','c','d')])   # 注意嵌套序列数量不一时,多维数组会变一维数组
print(ar1,type(ar1),ar1.dtype)
print(ar2,type(ar2),ar2.dtype)
print(ar3,ar3.shape,ar3.ndim,ar3.size)     # 二维数组,共6个元素
print(ar4,ar4.shape,ar4.ndim,ar4.size)     # 一维数组,共2个元素

# 输出
[0 1 2 3 4 5 6 7 8 9] <class 'numpy.ndarray'> int32
[ 1.    2.    3.14  4.    5.  ] <class 'numpy.ndarray'> float64
[['1' '2' '3']
 ['a' 'b' 'c']] (2, 3) 2 6
[[1, 2, 3] ('a', 'b', 'c', 'd')] (2,) 1 2

 1.2)arange()函数,类似range()

np.arange(10))   # 返回0-9,整型

np.arange(10.0) # 返回0.0-9.0,浮点型

np.arange(5,12) # 返回5-11

np.arange(5.0,12,2)  # 返回5.0-12.0,步长为2

np.arange(10000) # 如果数组太大而无法打印,NumPy会自动跳过数组的中心部分,并只打印边角

 1.3)linspace():返回在间隔[开始,停止] 上计算的num个均匀间隔的样本

ar1 = np.linspace(2.0, 3.0, num=5)

ar2 = np.linspace(2.0, 3.0, num=5, endpoint=False)

ar3 = np.linspace(2.0, 3.0, num=5, retstep=True)

print(ar1,type(ar1))
print(ar2)
print(ar3,type(ar3))
# numpy.linspace(start, stop, num=50, endpoint=True, retstep=False, dtype=None)
# start:起始值,stop:结束值
# num:生成样本数
# endpoint:如果为真,则包含最后一个数,否则不包含最后一个数。默认值为True。
# retstep:如果为真,返回(样本,步长),其中步长是样本之间的间距 → 输出为一个包含2个元素的元祖,第一个元素为array,第二个为步长


# 输出:
[ 2.    2.25  2.5   2.75  3.  ] <class 'numpy.ndarray'>
[ 2.   2.2  2.4  2.6  2.8]
(array([ 2.  ,  2.25,  2.5 ,  2.75,  3.  ]), 0.25) <class 'tuple'>

 1.4)zeros()/ zeros_like()/ ones()/ ones_like()

ar1 = np.zeros(5)  
ar2 = np.zeros((2,2), dtype = np.int)
print(ar1,ar1.dtype)
print(ar2,ar2.dtype)
print('------')
# numpy.zeros(shape, dtype=float, order='C'):返回给定形状和类型的新数组,用零填充。
# shape:数组纬度,二维以上需要用(),且输入参数为整数
# dtype:数据类型,默认numpy.float64
# order:是否在存储器中以C或Fortran连续(按行或列方式)存储多维数据。

ar3 = np.array([list(range(5)),list(range(5,10))])
ar4 = np.zeros_like(ar3)
print(ar3)
print(ar4)
print('------')
# 返回具有与给定数组相同的形状和类型的零数组,这里ar4根据ar3的形状和dtype创建一个全0的数组

ar5 = np.ones(9)
ar6 = np.ones((2,3,4))
ar7 = np.ones_like(ar3)
print(ar5)
print(ar6)
print(ar7)
# ones()/ones_like()和zeros()/zeros_like()一样,只是填充为1


# 输出:
[ 0.  0.  0.  0.  0.] float64
[[0 0]
 [0 0]] int32
------
[[0 1 2 3 4]
 [5 6 7 8 9]]
[[0 0 0 0 0]
 [0 0 0 0 0]]
------
[ 1.  1.  1.  1.  1.  1.  1.  1.  1.]
[[[ 1.  1.  1.  1.]
  [ 1.  1.  1.  1.]
  [ 1.  1.  1.  1.]]

 [[ 1.  1.  1.  1.]
  [ 1.  1.  1.  1.]
  [ 1.  1.  1.  1.]]]
[[1 1 1 1 1]
 [1 1 1 1 1]]

  1.5)eye()

np.eye()    # 创建一个正方的N*N的单位矩阵,对角线值为1,其余为0

print(np.eye(5))

# 输出:
[[ 1.  0.  0.  0.  0.]
 [ 0.  1.  0.  0.  0.]
 [ 0.  0.  1.  0.  0.]
 [ 0.  0.  0.  1.  0.]
 [ 0.  0.  0.  0.  1.]]

 

 2)多维数组属性

import numpy as np

ar = np.array([1,2,3,4,5,6,7])
print(ar)          # 输出数组,注意数组的格式:中括号,元素之间没有逗号(和列表区分)
print(ar.ndim)     # 输出数组维度的个数(轴数),或者说“秩”,维度的数量也称rank
print(ar.shape)    # 数组的维度,对于n行m列的数组,shape为(n,m)
print(ar.size)     # 数组的元素总数,对于n行m列的数组,元素总数为n*m
print(ar.dtype)    # 数组中元素的类型,类似type()(注意了,type()是函数,.dtype是方法)
print(ar.itemsize) # 数组中每个元素的字节大小,int32l类型字节为4,float64的字节为8
print(ar.data)     # 包含实际数组元素的缓冲区,由于一般通过数组的索引获取元素,所以通常不需要使用这个属性

 3)numpy 通用函数

  3.1)数组形状:.T/ .reshape()/ .resize()

ar1 = np.arange(10)
ar2 = np.ones((5,2))
print(ar1,'\n',ar1.T)
print(ar2,'\n',ar2.T)
print('------')
# .T方法:转置,例如原shape为(3,4)/(2,3,4),转置结果为(4,3)/(4,3,2) → 所以一维数组转置后结果不变

ar3 = ar1.reshape(2,5)     # 用法1:直接将已有数组改变形状             
ar4 = np.zeros((4,6)).reshape(3,8)   # 用法2:生成数组后直接改变形状
ar5 = np.reshape(np.arange(12),(3,4))   # 用法3:参数内添加数组,目标形状
print(ar1,'\n',ar3)
print(ar4)
print(ar5)
print('------')
# numpy.reshape(a, newshape, order='C'):为数组提供新形状,而不更改其数据,所以元素数量需要一致!!

ar6 = np.resize(np.arange(5),(3,4))
print(ar6)
# numpy.resize(a, new_shape):返回具有指定形状的新数组,如有必要可重复填充所需数量的元素。
# 注意了:.T/.reshape()/.resize()都是生成新的数组!!!



# 输出:
[0 1 2 3 4 5 6 7 8 9] 
 [0 1 2 3 4 5 6 7 8 9]
[[ 1.  1.]
 [ 1.  1.]
 [ 1.  1.]
 [ 1.  1.]
 [ 1.  1.]] 
 [[ 1.  1.  1.  1.  1.]
 [ 1.  1.  1.  1.  1.]]
------
[0 1 2 3 4 5 6 7 8 9] 
 [[0 1 2 3 4]
 [5 6 7 8 9]]
[[ 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  1  2  3]
 [ 4  5  6  7]
 [ 8  9 10 11]]
------
[[0 1 2 3]
 [4 0 1 2]
 [3 4 0 1]]

 

 3.2)数组的复制

ar1 = np.arange(10)
ar2 = ar1
print(ar2 is ar1)
ar1[2] = 9
print(ar1,ar2)
# 回忆python的赋值逻辑:指向内存中生成的一个值 → 这里ar1和ar2指向同一个值,所以ar1改变,ar2一起改变

ar3 = ar1.copy()
print(ar3 is ar1)
ar1[0] = 9
print(ar1,ar3)
# 使用copy方法可以实现完整复制,改变该数组值不影响原数组值


# 输出:
True
[0 1 9 3 4 5 6 7 8 9] [0 1 9 3 4 5 6 7 8 9]
False
[9 1 9 3 4 5 6 7 8 9] [0 1 9 3 4 5 6 7 8 9]

 

 3.3)数组类型转换:.satype()

# 实现数组类型转换

ar1 = np.arange(10,dtype=float)
print(ar1,ar1.dtype)
print('-----')
# 可以在参数位置设置数组类型

ar2 = ar1.astype(np.int32)
print(ar2,ar2.dtype)
print(ar1,ar1.dtype)
# a.astype():转换数组类型
# 注意:养成好习惯,数组类型用np.int32,而不是直接int32


# 输出:
[ 0.  1.  2.  3.  4.  5.  6.  7.  8.  9.] float64
-----
[0 1 2 3 4 5 6 7 8 9] int32
[ 0.  1.  2.  3.  4.  5.  6.  7.  8.  9.] float64

 

 3.4)数组简单运算

# 与标量的运算
ar = np.arange(6).reshape(2,3)
print(ar + 10)   # 加法
print(ar * 2)   # 乘法
print(1 / (ar+1))  # 除法
print(ar ** 0.5)  #


print(ar.mean())  # 求平均值
print(ar.max())  # 求最大值
print(ar.min())  # 求最小值
print(ar.std())  # 求标准差
print(ar.var())  # 求方差
print(ar.sum(), np.sum(ar,axis = 0))  # np.sum():求和 ; np.sum(ar,axis=0/1):axis为0,按列求和;axis为1,按行求和  ,注意看输出结果
print(np.sort(np.array([1,4,3,2,5,6])))  # 排序

 输出:

[[10 11 12]
 [13 14 15]]
[[ 0  2  4]
 [ 6  8 10]]
[[ 1.          0.5         0.33333333]
 [ 0.25        0.2         0.16666667]]
[[ 0.          1.          1.41421356]
 [ 1.73205081  2.          2.23606798]]
2.5
5
0
1.70782512766
2.91666666667
15 [3 5 7]
[1 2 3 4 5 6]

 

 4)numpy索引及切片

  4.1)基本索引及切片

# 一维数组索引及切片
ar = np.arange(20)
print(ar)
print(ar[4])
print(ar[3:6])
print('-----')

# 二维数组索引及切片
ar = np.arange(16).reshape(4,4)
print(ar, '数组轴数为%i' %ar.ndim)   # 4*4的数组
print(ar[2],  '数组轴数为%i' %ar[2].ndim)  # 切片为下一维度的一个元素,所以是一维数组
print(ar[2][1]) # 二次索引,得到一维数组中的一个值
print(ar[1:3],  '数组轴数为%i' %ar[1:3].ndim)  # 切片为两个一维数组组成的二维数组
print(ar[2,2])  # 切片数组中的第三行第三列 → 10
print(ar[:2,1:])  # 切片数组中的1,2行、2,3,4列 → 二维数组
print('-----')

# **三维数组索引及切片
ar = np.arange(8).reshape(2,2,2)
print(ar, '数组轴数为%i' %ar.ndim)   # 2*2*2的数组
print(ar[0],  '数组轴数为%i' %ar[0].ndim)  # 三维数组的下一个维度的第一个元素 → 一个二维数组
print(ar[0][0],  '数组轴数为%i' %ar[0][0].ndim)  # 三维数组的下一个维度的第一个元素下的第一个元素 → 一个一维数组
print(ar[0][0][1],  '数组轴数为%i' %ar[0][0][1].ndim)  


# 输出:
[ 0  1  2  3  4  5  6  7  8  9 10 11 12 13 14 15 16 17 18 19]
4
[3 4 5]
-----
[[ 0  1  2  3]
 [ 4  5  6  7]
 [ 8  9 10 11]
 [12 13 14 15]] 数组轴数为2
[ 8  9 10 11] 数组轴数为1
9
[[ 4  5  6  7]
 [ 8  9 10 11]] 数组轴数为2
10
[[1 2 3]
 [5 6 7]]
-----
[[[0 1]
  [2 3]]

 [[4 5]
  [6 7]]] 数组轴数为3
[[0 1]
 [2 3]] 数组轴数为2
[0 1] 数组轴数为1
1 数组轴数为0

 4.2)布尔型索引及切片(重要)

ar = np.arange(12).reshape(3,4)
i = np.array([True,False,True])
j = np.array([True,True,False,False])
print(ar)
print(i)
print(j)
print(ar[i,:])  # 在第一维度做判断,只保留True,这里第一维度就是行,ar[i,:] = ar[i](简单书写格式)
print(ar[:,j])  # 在第二维度做判断,这里如果ar[:,i]会有警告,因为i是3个元素,而ar在列上有4个

# 布尔型索引:以布尔型的矩阵去做筛选
m = ar > 5
print(m)  # 这里m是一个判断矩阵
print(ar[m])  # 用m判断矩阵去筛选ar数组中>5的元素 → 重点!后面的pandas判断方式原理就来自此处


# 输出:
[[ 0  1  2  3]
 [ 4  5  6  7]
 [ 8  9 10 11]]
[ True False  True]
[ True  True False False]
[[ 0  1  2  3]
 [ 8  9 10 11]]
[[0 1]
 [4 5]
 [8 9]]
[[False False False False]
 [False False  True  True]
 [ True  True  True  True]]
[ 6  7  8  9 10 11]

 

posted on 2019-08-01 17:25  Eric_nan  阅读(632)  评论(3编辑  收藏  举报