数据分析—01NumPy数据科学库

一、什么是NumPy

NumPy是使用Python进行科学计算的基础软件包。是 Python 语言的一个扩展程序库,支持大量的维度数组与矩阵运算,此外也针对数组运算提供大量的数学函数库。
除其他外,它包括:

    1 功能强大的N维数组对象。(数组中类型一样)
    2 精密广播功能函数。
    3 集成 C/C+和Fortran 代码的工具。
    4 强大的线性代数、傅立叶变换和随机数功能。

两个强大的功能:

  • N维数组对象Ndarray
    NumPy 最重要的一个特点是其 N 维数组对象 ndarray,它是一系列同类型数据的集合,以 0 下标为开始进行集合中元素的索引。ndarray 对象是用于存放同类型元素的多维数组。ndarray 中的每个元素在内存中都有相同存储大小的区域。
  • 切片和索引
    ndarray对象的内容可以通过索引或切片来访问和修改,与 Python 中 list 的切片操作一样。ndarray 数组可以基于 0 - n 的下标进行索引,切片对象可以通过内置的 slice 函数,并设置 start, stop 及 step 参数进行,从原数组中切割出一个新数组。

安装

pip install -i https://pypi.douban.com/simple numpy

二、用法

1、数组间的操作

# shape : 2×4
a = [
    [3, 4, 5, 6],
    [4, 5, 6, 7]
]
# shape : 3×4
c = [
    [1, 2, 3, 4],
    [5, 6, 7, 8],
    [9, 10, 11, 12]
]

# 没有numpy数据计算库时,数组+数组和线性代数的思维不同,+ 代表追加,不是对应位相加
# 有numpy数据计算库时,不能相加 维度不同
print( a + c)

# 数组中 * 代表重复的意思  [1] * 3 = [1, 1, 1] , 不是线性代数的矩阵相乘
# 有numpy数据计算库时,可以实现N维数组相乘

2、numpy创建数组

方法一:

import numpy as np

# 方法一: 直接将数组/列表传入array方法中,将数据类型转换维ndarray
a = np.array([1, 2, 3, 4])
print(a)            # [1 2 3 4]
print(type(a))      # <class 'numpy.ndarray'>

b = [
    [1, 2, 3, 4],
    [5, 6, 7, 8],
    [9, 10, 11, 12]
]
# 可以通过dtype来转换数据类型
# 数组中有小数出现,则在ndarray中元素全部存为浮点型
b_ndarray = np.array(b, dtype=np.float)
print(b_ndarray)
print(type(b_ndarray))

# 传入的值也可以是range对象
c = np.array(range(1,5))
print(c)       # [1 2 3 4]

方法二:

# 方法二: 使用 arange 直接生成指定的数值
# arange和range的基本语法和参数一致,不同的是arange可以生成小数区间
d = np.arange(2.5, 5, 0.5)  # 从2.5到5 步长为0.5
print(d)     # [2.5 3.  3.5 4.  4.5]

查看属性的方法:

# 查看属性 : 通过 对象名.dtype 进行查看
print(a.dtype)   # int32 硬件架构是32位

修改数据类型:

# 修改数据类型  对象名.astype
e = d.astype('int64')
print(e, e.dtype)

随机生成小数:

# random.random  生成0 - 1 之间的随机小数
# numpy中, 需要传入参数size : 生成多大的数组
f = np.random.random((3, 4))  # 生成3×4的
print(f)

修改浮点数的小数位

# 修改浮点数的小数位为3
g = np.round(f, 3)
print(g)

转换数据结构

# 转换数据结构  元素个数和转换前一样
# 将原来的b 3行4列 转换成 2行6列
b = b.reshape((2, 6))
print(b)

3、矩阵的转置

行列互换

import numpy as np

data = np.random.random((2, 6))
print(data)

# 转置: 行列互换,3种方法
print("转置:", data.T)
print("转置:", data.transpose())
# x, y 两个轴进行转换  0代表x轴 1代表y轴
print("转置:", data.swapaxes(1, 0))

4、索引和切片

import numpy as np
# np.arange(12) : [0 1 2 3 4 5 6 7 8 9 10 11]
a = np.arange(12).reshape((3, 4))
print(a)

# 取单行或者单列  a[i]:获取第i+1行  a[:, i]:获取第i+1列
# 取第2行
print(a[1])
# 取第3列
print(a[:, 2])
# 取第2行第3列的元素
print(a[1, 2])

# 取连续行或连续列
# 第2到第3行  a[i:j] :获取第i+1行到第j行
print(a[1:3])
# 第3到第4列  a[:, i:j] :获取第i+1列到第j列
print(a[:, 2:4])

# 取某几行某几列
# 取 1 2 行 2 3 列
print(a[0:2,1:3])

# 取不连续的行或者列
# 获取第1行和第3行
print(a[[0, 2], :])
# 获取第1列和第4列
print(a[:,[0, 3]])
#获取第1行和第3行 第1列和第4列
print(a[[0,2],[0,3]])

5、数值修改

import numpy as np

t = np.arange(24).reshape((4, 6))
print(t)

# 方法一: 根据索引或切片对元素进行赋值
# 将第3和第4列的值改为0
t[:,[2,3]] = 0
# t[:,[2:4]] = 0
print(t)

# 方法二: 布尔索引 满足条件则赋值,否则不修改
#print(t < 10)  # 返回的是元素是True / False    size不变
t[t < 10] = 100
print(t)

# 方法三: 三元运算符 t<100?0:10 小于100赋值为0,不小于赋值为10
t1 = np.where(t < 100, 0, 10)
print(t)
print(t1)

6、获取矩阵的四角元素

import numpy as np

x = np.arange(12).reshape((4, 3))  # 4行3列
print(x)
# 方法一: 按对应的索引获取
# 0:(0,0)  2:(0,2)  9:(3,0)  11(3, 2)
a = [
    x[0,0],x[0,2],
    x[3,0], x[3,2]
]
print(a)

# 方法二:
# rows = np.array([[0,0], [3,3]])
# cols = np.array([[0,2], [0,2]])
# print(x[rows, cols])

row, column = x.shape
rows = np.array([[0, 0], [row-1, row-1]])
cols = np.array([[0, column-1], [0, column-1]])
y = x[rows, cols]
print(y)

抽象出来

import numpy as np

def get_edge(data):
    """  获取矩阵的四角元素 """
    row, column = data.shape
    rows = np.array([[0, 0], [row - 1, row - 1]])
    cols = np.array([[0, column - 1], [0, column - 1]])
    return data[rows, cols]

if __name__ == '__main__':
    x = np.arange(30).reshape((5, 6))
    print('data:', x)
    print('result:', get_edge(x))

7、数组形状修改

import numpy as np

# 1. reshape

# 2. flat
a = np.arange(9).reshape(3, 3)
print(a)
for row in a:
    print(row)
# 使用flat属性 ,对数组中每个元素进行展开, 该属性是一个数组元素迭代器
for element in a.flat:
    print(element)

# 3. flatten
a = np.arange(8).reshape((2, 4))
print(a)
# 使用flatten属性,直接将元素展开
print(a.flatten())   # [0 1 2 3 4 5 6 7] 默认按行展开
print(a.flatten(order='F'))  # [0 4 1 5 2 6 3 7] 按列展开

# 4. ravel
a = np.arange(8).reshape((2, 4))
print(a)
print(a.ravel())     # [0 1 2 3 4 5 6 7]
print(a.ravel(order='F'))  # [0 4 1 5 2 6 3 7]

8、数组拼接

import numpy as np

a = np.array([[1,2], [3,4]])
b = np.array([[5,6], [7,8]])
print(a)
print(b)

# 1. concatenate 水平/竖直拼接 需要有参数设置
# x轴:0  y轴:1
print(np.concatenate((a,b)))  # 默认竖直拼接
print(np.concatenate((a,b), axis=1))  # 水平拼接

# 2. stack 堆积 水平/竖直
print(np.stack((a,b), axis=0))
stack_0 = np.stack((a,b), axis=0)
print(stack_0.shape)       # (2, 2, 2)
print(np.stack((a,b), axis=1))

# 3. hstack 水平拼接起来 矩阵的行数要一致
c = np.hstack((a, b))
print(c)

# 4. vstack 竖直拼接起来 矩阵的列数要一致
d = np.vstack((a, b))
print(d)

9、数组分割

import numpy as np

a = np.arange(9)
print(a)        # [0 1 2 3 4 5 6 7 8]

# 1. split
# 切割成3等分
b = np.split(a, 3)
print(b)        # [array([0, 1, 2]), array([3, 4, 5]), array([6, 7, 8])]
# 从指定位置切割
b = np.split(a, [2, 7])   # [array([0, 1]), array([2, 3, 4, 5, 6]), array([7, 8])]
print(b)

# 2. hsplit  按列(水平)切割
c = np.arange(12).reshape((3, 4))
print(c)
print(np.hsplit(c, 2))   # 将4列等分成2列

# 3. vsplit  按行(竖直)切割
d = np.arange(12).reshape((4, 3))
print(d)
print(np.vsplit(d, 2))  # 将4行等分成2行

10、数组元素的增加与删除

"""
    resize 返回指定形状的新数组
    append 将值添加到数组末尾
    insert 沿指定轴将值插入到指定下标之前
    delete 删掉某个轴的子数组,并返回删除后的新数组
    unique     查找数组内的唯一元素
            arr:输入数组,如果不是一维数组则会展开
            return_index:如果为true,返回新列表元素在旧列表中的位置(下标),并以列表形式储
            return_counts:如果为true,返回去重数组中的元素在原数组中的出现次数
"""
import numpy as np

# append
a = np.array([[1,2,3], [4,5,6]])
print(a)
# 没有指定行/列追加时, 默认是将元素展开追加到后面
print(np.append(a, [7,8,9]))   # [1 2 3 4 5 6 7 8 9]
# 竖直追加 沿x轴
print(np.append(a, [[7,8,9]], axis=0))
# 水平追加 沿y轴
print(np.append(a, [[5,5,5], [6,6,6]], axis=1))

# insert
b = np.array([[1,2], [3,4], [5,6]])
print(b)
# 没有指定行/列时,默认将元素展开,插入到指定索引之前
print(np.insert(b, 3, [0, 0]))   # [1 2 3 0 0 4 5 6]
# 在指定行之前插入 x轴
print(np.insert(b, 1, [0, 0], axis=0))
# 在指定列之前插入 y轴
print(np.insert(b, 1, [0, 0, 0], axis=1))

# delete
c= np.arange(12).reshape((3,4))
print(c)
print(np.delete(c, 5))   # 将元素展开 删掉指定索引的那个元素
print(np.delete(c, 1, axis=0))  # 水平删
print(np.delete(c, 1, axis=1))  # 竖直删
# 使用切片对象删除, 从头开始,到结束,步长为2
print(np.delete(c, np.s_[::2]))  # [ 1  3  5  7  9 11]
print(np.delete(c, np.s_[::2], axis=0))
print(np.delete(c, np.s_[::2], axis=1))

# unique 去除重复元素,默认会排序
d = np.array([4,6,3,8,2,6,9,6])
print(d)
e = np.unique(d)   # [2 3 4 6 8 9]
print(e)
# 去重,并返回索引
f, index = np.unique(d, return_index=True)
print(index)      # [4 2 0 1 3 6]
# 去重, 并返回元素的重复的数量
g, counts = np.unique(d, return_counts=True)
print(counts)     # [1 1 1 3 1 1]

11、统计函数

"""
numpy.amin() 
用于计算数组中的元素沿指定轴的最小值。
numpy.amax() 
用于计算数组中的元素沿指定轴的最大值。
numpy.ptp()
函数计算数组中元素最大值与最小值的差(最大值 - 最小值)。
numpy.percentile()
 百分位数是统计中使用的度量,表示小于这个值的观察值的百分比。
numpy.median() 
函数用于计算数组 a 中元素的中位数(中值)
numpy.mean() 
函数返回数组中元素的算术平均值。 如果提供了轴,则沿其计算。 各个值的权重一样
numpy.average() 
函数根据在另一个数组中给出的各自的权重计算数组中元素的加权平均值。   average()
np.std()    
标准差是一组数据平均值分散程度的一种度量。
    标准差公式如下:std = sqrt(((x - x.mean())**2))/n
np.var()    
统计中的方差(样本方差)是每个样本值与全体样本值的平均数之差的平方值的平均数,即 ((x - x.mean())** 2)/n。
     标准差是方差的平方根。
"""

学生身高体重统计分析案例

"""
需求1:
    获取所有男生的身高, 求平均值;获取所有女生的身高, 求平均值;并绘制柱状图显示
需求2:
    获取所有男生的体重, 求平均值;获取所有女生的体重, 求平均值;并绘制柱状图显示
"""
import numpy as np
def get_avg_height():
    fname = "doc/eg6-a-student-data.txt"
    # 定义读取列的数据类型
    dtype = np.dtype([('gender', '|S1'), ('height', 'f2')])
    # 读取文件的第2列和第3列, 前9行忽略;
    data = np.loadtxt(fname=fname, dtype=dtype, skiprows=9,
                      usecols=(1, 3))
    # print(data)
    # print(data['gender'])
    # print(data['height'])
    # print(data['height'][data['gender'] == b'M'].mean())
    # print(data['height'][data['gender'] == b'F'].mean())

    # 判断是否性别为那男的表达式
    isMale = data['gender'] == b'M'
    male_avg_height = data['height'][isMale].mean()
    # ~代表取反
    female_avg_height = data['height'][~isMale].mean()
    return male_avg_height, female_avg_height
def parser_weight(weight):
    # 对于体重数据的处理, 如果不能转换为浮点数据类型, 则返回缺失值;
    try:
        return  float(weight)
    except ValueError as e:
        return  -99
def get_avg_weight():
    fname = "doc/eg6-a-student-data.txt"
    # 定义读取列的数据类型
    dtype = np.dtype([('gender', '|S1'), ('weight', 'f2')])
    # 读取文件的第2列和第4列, 前9行忽略;
    data = np.loadtxt(fname=fname, dtype=dtype, skiprows=9,
                      usecols=(1, 4), converters={4:parser_weight})

    # 判断是否性别为男的平均身高
    isMale = data['gender'] == b'M'

    # 判断是否性别为男的平均体重
    is_weight_vaild = data['weight'] > 0
    male_avg_weight = data['weight'][isMale & is_weight_vaild].mean()
    female_avg_weight = data['weight'][~isMale & is_weight_vaild].mean()
    return  male_avg_weight, female_avg_weight
if __name__ == '__main__':
    print(get_avg_height())
    print(get_avg_weight())
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值