Python数据分析

Posted 雨宙

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Python数据分析相关的知识,希望对你有一定的参考价值。

Python数据分析(一)

打卡第五天啦!!!

Numpy库(一)

介绍

  1. 功能强大的Python库,主要用于对多维数组执行计算
  2. 非常高效的用于处理数值型运算的包
  3. 通过pip install numpy安装
  4. numpy数组和Python列表性能对比
import numpy as np
import time
t1 = time.time()
a = []
for x in range(1000000):
    a.append(x**2)
    pass
t2 = time.time()
print(t2-t1)
# 0.3191087245941162
t3 = time.time()
b = np.arange(1000000)**2
t4 = time.time()
print(t4-t3)
# 0.006983041763305664

数组的创建方式

  1. numpy中的数组和Python中的列表的区别:
    (1)一个列表中可以存储多种数据类型,而数组只能存储同种数据类型
    (2)数组可以是多维的,当多维数组中的所有的数据都是数值类型的时候,相当于线性代数中的矩阵,是可以进行相互间的运算的
  2. 创建数组的四种方式:
    (1)使用np.array来创建
    (2)使用np.arange来创建一个区间的数组
    (3)使用np.random模块来创建
    (4)使用np上面的一些特殊函数来创建
import numpy as np
# 使用np.array创建数组
a1 = np.array([1,2,3,4])
print(a,type(a))
# [1 2 3] <class 'numpy.ndarray'>
# 使用np.arange创建数组
a2 = np.arange(10)
print(a2)
# [0 1 2 3 4 5 6 7 8 9]
a3 = np.arange(0,10,2)
print(a3)
# [0 2 4 6 8]
# 使用np.random.random来创建一个N行N列的数组,其中里面的值是0-1之间的随机数
a4 = np.random.random((2,2))
print(a4)
# [[0.37701883 0.5439565 ]
#  [0.23671606 0.54575213]]
# 使用np.random.randint来创建一个N行N列的数组,其中值的范围可以通过前面2个参数来指定
a5 = np.random.randint(0,9,size=(3,3))
print(a5)
# [[0 8 1]
#  [2 8 7]
#  [0 5 6]]
# 特殊函数
b = np.zeros((3,3))
print(b)
# [[0. 0. 0.]
#  [0. 0. 0.]
#  [0. 0. 0.]]
b1 = np.ones((4,4))
print(b1)
# [[1. 1. 1. 1.]
#  [1. 1. 1. 1.]
#  [1. 1. 1. 1.]
#  [1. 1. 1. 1.]]
b2 = np.full((2,3),4)
print(b2)
# [[4 4 4]
#  [4 4 4]]
b3 = np.eye(3)
print(b3)
# [[1. 0. 0.]
#  [0. 1. 0.]
#  [0. 0. 1.]]

数组的数据类型

  1. 数据类型多:基于C语言编写,C语言中有很多数据类型,直接引用过来,而且为了考虑处理海量数据的性能,针对不同的数据给不同的数据类型,来节省内存空间
  2. 具体数据类型分类
a = np.arange(9)
print(a)
print(a.dtype)
# [0 1 2 3 4 5 6 7 8]
# int32
b = np.array([1,2,3,4],dtype=np.int8)
print(b)
print(b.dtype)
# [1 2 3 4]
# int8
c = np.array([1,2,3,4],dtype=np.float16)
print(c)
print(c.dtype)
# [1. 2. 3. 4.]
# float16
class Person:
    def __init__(self,name,age):
        self.name = name
        self.age = age
        pass
d = np.array([Person('潘小雷',20),Person('鲸鱼',20)])
print(d)
print(d.dtype)
# [<__main__.Person object at 0x000001DE69ACF130>
#  <__main__.Person object at 0x000001DE69ACF460>]
# object
  1. 数据类型转换 ndarray.astype
# 类型转换
f = np.array(['a','b'],dtype='S')
print(f)
print(f.dtype)
uf = f.astype('U')
print(uf)
print(uf.dtype)
# [b'a' b'b']
# |S1
# ['a' 'b']
# <U1

多维数组及其简单操作

  1. 一般把三维以上的数组转化为二维计算
  2. 通过ndarray.ndim可以看到数组的维度
# 数组的维数
a1 = np.array([1,2,3])
print(a1.ndim) # 1
a2 = np.array([[1,2,3],[4,5,6]])
print(a2.ndim) # 2
a3 = np.array([
    [
        [1,2,3],
        [4,5,6]
    ],
    [
        [7,8,9],
        [10,11,12]
    ]
])
print(a3.ndim) # 3
  1. 通过ndarray.shape可以看到数组的形状(几行几列),shape是一个元组,里面有几个元素代表是几维数组
# 数组的维度的元组
a1 = np.array([1,2,3])
print(a1.shape) 
a2 = np.array([[1,2,3],[4,5,6]])
print(a2.shape) 
a3 = np.array([
    [
        [1,2,3],
        [4,5,6]
    ],
    [
        [7,8,9],
        [10,11,12]
    ]
])
print(a3.shape) 
  1. 通过ndarray.reshape可以修改数组的形状,条件只有一个,就是修改后的形状的元素个数必须与原来的个数一致。不会修改原来数组的形状,只会将修改后的结果返回
a4 = a3.reshape((2,6))
print(a4)
# [[ 1  2  3  4  5  6]
#  [ 7  8  9 10 11 12]]
a5 = a3.reshape((12,))
a5 = a3.flatten() # 扁平化
print(a5)
# [ 1  2  3  4  5  6  7  8  9 10 11 12]
  1. 通过ndarray.size可以看到数组总共有多少个元素
count = a3.size
print(count) #12
  1. 通过ndarray.itemsize可以看到数组中每个元素所占内存的大小,单位是字节(1个字节=8位)
# 获取每一个元素所占的字节大小
itemsize = a3.itemsize
print(itemsize) #4

数组的索引和切片

  1. 如果数组是一维的,那么索引和切片就是跟python的列表是一样的。
# 一维数组索引和切片
a1 = np.arange(10)
print(a1[4])
print(a1[4:6])
print(a1[::2])
print(a1[-1])
# 4
# [4 5]
# [0 2 4 6 8]
# 9
  1. 如果是多维的(这里以二维为例),那么在中括号中,给两个值,两个值是通过逗号分隔的,逗号前面的是行,逗号后面的是列。如果中括号中只有一个值,那么就是代表的是行。
  2. 如果是多维数组(这里以二维为例),那么行的部分和列的部分,都是遵循一维数组的方式,可以使用整形,切片,还可以使用中括号的形式,来代表不连续的。比如a[[1,2],[3.4]],那么返回的就是(1,3),(2,4)的两个值。
# 多维数组索引和切片
# 通过中括号来索引和切片,在中括号中,使用逗号进行分割
a2 = np.random.randint(0,10,size=(4,6))
print(a2)
print(a2[0])
print(a2[0:2])     # 切片获取行
print(a2[[0,2,3]]) # 获取不连续的行
print(a2[1,1])     # 获取某一个数据
print(a2[[1,2],[4,5]]) # 第一行第四列 第二行第五列 不连续的数据
print(a2[1:3,4:6])  # 获取连续的数据
print(a2[:,1])     # 获取第一列数据
# [[9 8 2 7 8 1]
#  [6 1 1 1 2 7]
#  [2 3 3 6 7 6]
#  [4 0 5 8 0 2]]
# [9 8 2 7 8 1]
# [[9 8 2 7 8 1]
#  [6 1 1 1 2 7]]
# [[9 8 2 7 8 1]
#  [2 3 3 6 7 6]
#  [4 0 5 8 0 2]]
# 1
# [2 6]
# [[2 7]
#  [7 6]]
# [8 1 3 0]

布尔索引

  1. 布尔索引是通过相同数组上的True还是False进行提取的,提取的条件可有多个,用&表示且,用|表示或,如果有多个条件,每个条件要使用圆括号括起来
a2 = np.arange(24).reshape((4,6))
print(a2)
print(a2 < 10)
print(a2[a2 < 10])
print(a2[(a2 < 5) & (a2 > 1)])
# [[ 0  1  2  3  4  5]
#  [ 6  7  8  9 10 11]
#  [12 13 14 15 16 17]
#  [18 19 20 21 22 23]]
# [[ True  True  True  True  True  True]
#  [ True  True  True  True False False]
#  [False False False False False False]
#  [False False False False False False]]
# [0 1 2 3 4 5 6 7 8 9]
# [2 3 4]

数组值的替换

  1. 可以使用索引或切片来替换
a3 = np.random.randint(0,10,size=(3,5))
print(a3)
a3[1] = np.array([1,2,3,4,5])
print(a3)
# [[5 6 9 6 1]
#  [2 0 3 8 8]
#  [0 0 1 0 0]]
# [[5 6 9 6 1]
#  [1 2 3 4 5]
#  [0 0 1 0 0]]
  1. 可以使用条件索引来替换
a3[ a3 < 3] = 1
print(a3)
# [[5 6 9 6 1]
#  [1 1 3 4 5]
#  [1 1 1 1 1]]
  1. 使用where函数实现
res = np.where(a3 < 5, 0 , 1)
print(res)
# [[1 1 1 1 0]
#  [0 0 0 0 1]
#  [0 0 0 0 0]]

数组的广播机制

  1. 数组和数字直接进行运算是可以的
a1 = np.random.randint(0,5,size=(3,5))
print(a1)
print(a1*2)
# [[3 3 0 0 4]
#  [4 3 1 0 2]
#  [1 3 2 3 0]]
# [[6 6 0 0 8]
#  [8 6 2 0 4]
#  [2 6 4 6 0]]
  1. 两个shape相同的数组是可以进行运算的
a2 = np.random.randint(0,5,size=(3,5))
print(a2)
print(a1+a2)
# [[2 2 4 0 0]
#  [0 1 2 2 2]
#  [2 2 4 0 3]]
# [[5 5 4 0 4]
#  [4 4 3 2 4]
#  [3 5 6 3 3]]
  1. 如果两个shape不同的数组,想要进行运算,那么需要看他们是否满足广播原则
a3 = np.random.randint(0,5,size=(3,4))
a4 = np.random.randint(0,5,size=(3,1))
print(a4)
print(a1+a4)
# [[3]
#  [4]
#  [1]]
# [[6 6 3 3 7]
#  [8 7 5 4 6]
#  [2 4 3 4 1]]
  1. 广播原则:如果两个数组的后缘维度(即从末尾开始算起的维度)的轴长度相符或其中一方的长度为1,则认为他们是广播兼容的,广播会在缺失和(或)长度为1的维度上进行

数组形状操作

reshape、resize、flatten、ravel

  1. reshape和resize都是重新定义形状的。但是reshape不会修改数组本身,而是将修改后的结果返回回去,而resize是直接修改数组本身的。
a1 = np.random.randint(0,10,size=(3,4))
print(a1)
# [[0 6 0 9]
#  [0 3 6 9]
#  [5 5 3 6]]
a2 = a1.reshape((2,6))
print(a2)
# [[0 6 0 9 0 3]
#  [6 9 5 5 3 6]]
print(a1)
# [[0 6 0 9]
#  [0 3 6 9]
#  [5 5 3 6]]
a1.resize((4,3))
print(a1)
# [[0 6 0]
#  [9 0 3]
#  [6 9 5]
#  [5 3 6]]
  1. flatten和ravel都是用来将数组边成一维数组的,并且他们都不会对原数组造成修改,但是flatten返回的是一个拷贝,所以对flatten的返回值的修改不会影响到原来数组,而ravel返回的是一个View,那么对返回值的修改会影响到原来数组的值。
a2 = np.random.randint(0,10,size=(3,4))
print(a2)
# [[5 7 6 4]
#  [6 8 1 7]
#  [5 7 6 2]]
print(a2.flatten())
# [5 7 6 4 6 8 1 7 5 7 6 2]
print(a2)
# [[5 7 6 4]
#  [6 8 1 7]
#  [5 7 6 2]]
print(a2.ravel())
# [5 7 6 4 6 8 1 7 5 7 6 2]
print(a2)
# [[5 7 6 4]
#  [6 8 1 7]
#  [5 7 6 2]]
a3 = a2.flatten()
a4 = a2.ravel()
a3[0] = 100
print(a2)
# [[5 7 6 4]
#  [6 8 1 7]
#  [5 7 6 2]]
a4[0] = 100
print(a2)
# [[100   7   6   4]
#  [  6   8   1   7]
#  [  5   7   6   2]]

数组的叠加

  1. hstack代表在水平方向叠加,如果想要叠加成功,那么他们的行必须一致。
h1 = np.random.randint(0,10,size=(3,4))
print(h1)
h2 = np.random.randint(0,10,size=(3,2))
print(h2)
# [[5 1 3 0]
#  [0 0 3 5]
#  [8 1 7 6]]
# [[8 4]
#  [5 6]
#  [1 8]]
h3 = np.hstack([h1,h2])
print(h3)
# [[5 1 3 0 8 4]
#  [0 0 3 5 5 6]
#  [8 1 7 6 1 8]]
  1. vstack代表在垂直方向叠加,如果想要叠加成功,那么他们的列必须一致。
vstack1 = np.random.randint(0,10,size=(3,4))
print(vstack1)
vstack2 = np.random.randint(0,10,size=(2,4))
print(vstack2)
# [[3 5 0 3]
#  [2 5 7 3]
#  [6 2 8 0]]
# [[1 1 4 2]
#  [1 3 9 6]]
vstack3 = np.vstack([vstack1,vstack2])
print(vstack3)
# [[3 5 0 3]
#  [2 5 7 3]
#  [6 2 8 0]
#  [1 1 4 2]
#  [1 3 9 6]]
  1. concatenate可以手动的指定axis参数具体在哪个方向叠加,如果axis=0,代表在垂直方向叠加,如果axis=1,代表在水平方向叠加,如果axis=None,那么会先进行叠加,再转换成1维数组。
v3 = np.concatenate([vstack1,vstack2],axis=0)
print(v3)
# [[3 5 0 3]
#  [2 5 7 3]
#  [6 2 8 0]
#  [1 1 4 2]
#  [1 3 9 6]]
h3 = np.concatenate([h1,h2],axis=1)
print(h3)
# [[5 1 3 0 8 4]
#  [0 0 3 5 5 6]
#  [8 1 7 6 1 8]]
h4 = np.concatenate([h1,h2],axis=None)
print(h4)
# [5 1 3 0 0 0 3 5 8 1 7 6 8 4 5 6 1 8]

数组切割

  1. hsplit代表在水平方向切割,按列进行切割的。他的切割方式有两种,第一种就是直接指定平均切割成多少列,第二种就是指定切割的下标值。
hs1 = np.random.randint(0,10,size=(3,4))
print(hs1)
# [[8 4 2 1]
#  [5 6 2 1]
#  [6 5 7 0]]
np.hsplit(hs1,2)
# [array([[8, 4],
#         [5, 6],
#         [6, 5]]),
#  array([[2, 1],
#         [2, 1],
#         [7, 0]])]
np.hsplit(hs1,(1,2))
# [array([[8],
#         [5],
#         [6]]),
#  array([[4],
#         [6],
#         [5]]),
#  array([[2, 1],
#         [2, 1],
#         [7, 0]])]
  1. vsplit代表在垂直方向切割,按行进行切割。他的切割方式跟hsplit是一样的。
vs1 = np.random.randint(0,10,size=(4,5))
print(vs1)
# [[8 7 6 7 9]
#  [1 9 2 5 9]
#  [4 9 2 2 8]
#  [8 6 4 4 1]]
np.vsplit(vs1,4)
# [array([[8, 7, 6, 7, 9]]),
#  array([[1, 9, 2, 5, 9]]),
#  array([[4, 9, 2, 2, 8]]),
#  array([[8, 6, 4, 4, 1]])]
np.vsplit(vs1,(1,3))
# [array([[8, 7, 6, 7, 9]]),
#  array([[1, 9, 2, 5, 9],
#         [4, 9, 2, 2, 8]]),
#  array([[8, 6, 4, 4, 1]])]
  1. split/array_split是手动的指定axis参数,axis=0,代表按行进行切割,axis=1,代表按列进行切割。
np.split(hs1,4,axis=1)
# [array([[8],
#         [5],
#         [6]]),
#  array([[4],
#         [6],
#         [5]]),
#  array([[2],
#         [2],
#         [7]]),
#  array([[1],
#         [1],
#         [0]])]
np.split(vs1,4,axis=0)
# [array([[8, 7, 6, 7, 9]]),
以上是关于Python数据分析的主要内容,如果未能解决你的问题,请参考以下文章

python括号区别

Python和MATLAB的小括号( )、中括号[ ]和大括号

python程序括号为啥变绿

在python中使用嵌套子括号删除双波浪括号之间的数据

python数据结构--有效的括号

数据分析基本流程 Python基本数据类型 Python各种括号的使用方式