python_new
  • Introduction
  • First Chapter
  • 一、python基础
    • 1.1 常识
      • sys
    • 1.2 基础语法(1)
    • 1.2 基础语法(2)
    • 1.3 常见问题求解
    • 1.4 算法
  • 二、爬虫
    • urllib库(1)
      • urllib库(2)
    • requests模块(1)
      • requests模块(2)
    • 2.1 爬虫基础(3)HTTP原理
    • 2.1 爬虫基础(4)会话和Cookies
    • 2.1 爬虫基础(5)数据存储
      • Mysql存储
      • MongoDB存储
      • Redis存储
    • 2.3 正则表达式
    • 2.4 解析库lxml
      • BeautifulSoup
      • pyquery(1)
      • pyquery(2)
    • 2.5 selenium(1)
    • 2.5 seleium(2)
    • 2.6 Json
    • 2.7 scrapy
      • scrapy(2)
    • 2.9 异步加载
    • 2.6 Splash
  • ORM框架
    • SQLAlchemy
  • Django
    • 1、初阶(一)
    • 初学:投票教程(一)
    • 初学:投票教程(二)
    • 初学:投票教程(三)
    • 初学:投票教程(总结)
    • 模型(一)
    • 模型(二)
    • 视图(一)
    • 视图(二)
    • 模板(一)
    • django实际使用笔记
  • 面试题收集总结
    • 数据结构原理
    • 算法篇
      • 排序
    • 题目篇
  • python数据分析
    • 基础了解(一)
    • 基础了解(二)
    • 基础了解(三)
  • 多线程
  • 深度学习
    • 疑问
  • keras(一)
  • 神经网络
  • 图像识别
  • Docker
    • 一、基础了解
Powered by GitBook
On this page
  • 一、Numpy 基础
  • 1、numpy 介绍
  • 2、数组对象
  • 3、通用函数:快速点对点数组函数
  • 4、数组导向编程

Was this helpful?

  1. python数据分析

基础了解(一)

Previouspython数据分析Next基础了解(二)

Last updated 6 years ago

Was this helpful?

主要涉及到python相关数据分析库的基础了解

参考资料:

其他:

一、Numpy 基础

1、numpy 介绍

numpy是python数值计算领域很重要的包。主要有以下特点:

  • ndarray,一个有效的多维有效数组,能提供以数组为导向的快速数值计算和灵活的广播功能(broadcasting)

什么是“灵活的广播功能”?

简单讲就是两个维度不同的矩阵进行按位加减操作时,进行的兼容操作

相关介绍:

  • 便利的数学函数

  • 用于读写/写入数据到磁盘的便利工具

  • 线性代数、随机数、傅里叶变换能力

  • 可以用C API来写C,C++或者FORTRAN

不解,这是什么操作?

2、数组对象

n维数组对象或者ndarray是numpy的关键特征

>>> import numpy as np
>>> data = np.random.randn(2,3)
>>> data
array([[-0.63472407, -0.93065189,  0.52834126],
       [-0.79213003, -0.25700294,  1.47626494]])
>>> data * 10
array([[-6.34724069, -9.30651888,  5.28341258],
       [-7.9213003 , -2.57002942, 14.76264944]])
>>> data + data
array([[-1.26944814, -1.86130378,  1.05668252],
       [-1.58426006, -0.51400588,  2.95252989]])
>>> data.shape
(2, 3)
>>> data.dtype
dtype('float64')

1、创建数组对象

  • np.array()

data1 = [6, 7.5, 8, 0, 1]
arr1 = np.array(data1)
# arr1
# array([ 6. ,  7.5,  8. ,  0. ,  1. ])

这里觉得很奇怪,为什么小数点后面是空格,而不是0?而且我发现[[1,2,3],[1,2]]这个数据居然不会报错,但是也很奇怪。

这个其实不奇怪,python中也有后面带有一个小数点的情况

  • arr.ndim

返回数组的行数

  • arr.shape

返回一个元组,包含数组的行数和列数

  • arr.dtype

一般在生成数组是,np.array()会自动匹配类型

有趣的是,我试过一个数组中加入字符串,也是可以的,只不过数组类型发生了变化,不是数字的而已。这是否说明这种数组类型,不仅可以处理数学操作,也可以实现一些其他数据类型的操作呢?

  • np.zeros(10)

生成一个array([ 0., 0., 0., 0., 0., 0., 0., 0., 0., 0.])

  • np.zeros((3,6))

同上

  • np.empty((2,3,2))

这个方法不能保证返回的数组中的数值都是0,有可能会返回某些垃圾数值,如下

array([[[  0.00000000e+000,   0.00000000e+000],
        [  2.16538378e-314,   2.16514681e-314],
        [  2.16511832e-314,   2.16072529e-314]],

       [[  0.00000000e+000,   0.00000000e+000],
        [  2.14037397e-314,   6.36598737e-311],
        [  0.00000000e+000,   0.00000000e+000]]])
  • np.arange(15)

生成array([ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14])

其他创建数组的函数

  • asarray:将传入数据转换为对应格式的ndarray,如果已经是目标的ndarray,则不copy

  • ones、ones_like:根据执行的格式和dtype创建一个全是1的数组;格局传入的数组格式,创建一个格式相同的全一数组

  • zeros、zeros_like:同上

  • empty、empty_like:创建新数组,只分配内存空间,但不填充任何值

  • eye、identity:创建N*N的单位矩阵(对角线为1,其余为0)

empty的例子前面出现过,其实是有值的,为什么说是没有值呢?另外,创建empty之后,如果输出值,有没有输出呢?

还有eye和identity应该有些差别吧?

2、ndarrays的数据类型

创建数据时,可以声明创建的数据类型

arr1 = np.array([1, 2, 3], dtype=np.float64)
arr2 = np.array([1, 2, 3], dtype=np.int32)

dtype才是numpy能灵活处理其他外界数据的原因。

类型介绍:

  • int7, uint8

  • int16, uint16

  • int32,uint32

  • int64, uint64

  • float16

  • float32

  • float64

  • float128

  • complex64

  • complex128

  • complex256

  • bool

  • object

  • string_

  • unicode_

转换数据类型:

  • ndarray.astype()

转换数据类型

float_arr = arr.astype(np.float64)

在转换不同的数据类型时,需要格外注意,比如由float转为int时,会截断小数点后面的数值。

3、数组计算

数组之所以重要,是因为不用写for循环就能表达很多操作

# 相乘
arr * arr
# 相减
arr - arr
# 标量运算
1 / arr
arr ** 0.5
# 数组比较,返回布尔数组
arr2 > arr

4、基本的索引和切片

  • 切片

# arr array([0, 1, 2, 3, 4, 5, 6, 7, 8, 9])
arr[5:8] = 12
# array([ 0,  1,  2,  3,  4, 12, 12, 12,  8,  9])

这里有个区别在numpy的array和python的list之间,list的切片是生成了一个新的list,修改是不会影响原本的list,但是array的切片创建的是一个视图,如果修改是会影响到原本的array的。

arr_slice = arr[5:8]
arr_slice[1] = 12345
# arr array([    0,     1,     2,     3,     4,    12, 12345,    12,     8,     9])

即便赋值给另一个变量,修改也会影响到原来的array的

如果需要复制的话,可以使用arr[5:8].copy

切片可以被赋值为数组,也可以被赋值为标量,当为标量的时候,所有切片数组中的元素都会变为标量的值。

  • 索引

索引很简单,就是普通理解的两种

arr2d[0][2]
arr2d[0, 2]
  • 用切片索引

对于一个多维数组

# 前两行
arr2d[:2]
# 前两行,后两列
arr2d[:2, 1:]
# 全部行,第一列
arr2d[:, :1]

提取出来之后,当然也可以赋值为标量或者数组,但是仍然这只是视图,会影响到原array的。

5、布尔索引

names = np.array(['Bob', 'Joe', 'Will', 'Bob', 'Will', 'Joe', 'Joe'])

data = np.random.randn(7, 4)

假设每一个名字对应data中的一行,我们希望提取出‘Bob’的那些行

names == 'Bob'
# array([ True, False, False,  True, False, False, False], dtype=bool)

然后就可以把这个布尔数组作为索引

data[names == 'Bob']

注意:布尔数组的长度要和data数组的长度一样长

  • 否定有两种方式

name != 'Bob'
data[~(names == 'Bob')]

第二种方式在反转已有的条件时,会很方便。

  • 多个布尔条件用布尔运算符&,|,另外python的and和or不管用

mask = (names == 'Bob') | (names == 'Will')
  • 修改值

data[data < 0] = 0

这也太方便了吧!?

6、花式索引

  • 提取行

arr[[4, 3, 0, 6]]可以从数组中提取出第4、3、0、6行,然后组成新的数组,arr[[-3, -5, -7]]也可以,允许从后面找

  • 提取多个特定数值

arr[[1, 5, 7, 2], [0, 3, 1, 2]]可以从数组中提取第(1,0), (5,3), (7,1),(2,2)个数值,前者代表行数,后者代表列数,共四个数字,以数组的形式按顺序排列返回。

  • 提取一个矩形局域

arr[[1, 5, 7, 2]][:, [0, 3, 1, 2]]这个较为复杂,首先[[1, 5, 7, 2]]这一部分将[0, 3, 1, 2]行提取出来,然后[:, [0, 3, 1, 2]]表示选中所有的行,但是列的顺序要按[0, 3, 1, 2]的顺序来排。

第二部分(变换列顺序)的使用感觉有些陌生

7、数组转置和轴交换

  • 数组转置

有两种方式,但注意的是转置是返回一个视图,而不是新的数组

arr.reshape((row, column))
arr.T

计算矩阵乘法的时候经常会用到,np.dot()

np.dot(arr.T, arr)
  • 轴变换

对于多维数组,transpose会接受由轴数字组成的tuple,来交换轴

刚开始这段还没看懂,稍微有点复杂

arr = np.arange(16).reshape((2, 2, 4))
arr
array([[[ 0,  1,  2,  3],
        [ 4,  5,  6,  7]],

       [[ 8,  9, 10, 11],
        [12, 13, 14, 15]]])

arr.transpose((1, 0, 2))
array([[[ 0,  1,  2,  3],
        [ 8,  9, 10, 11]],

       [[ 4,  5,  6,  7],
        [12, 13, 14, 15]]])

转换的方式是把索引按照轴数字来变换,原本轴数字应该是(0,1,2),看arr的第一行是没有发生变化的,因为它的前两个数字都是0,而最后一行也没变,是因为,前两个索引数字都是1。

arr
array([[[ 0,  1,  2,  3],
        [ 4,  5,  6,  7]],

       [[ 8,  9, 10, 11],
        [12, 13, 14, 15]]])

arr.swapaxes(1, 2)
# 交换轴2和轴一

array([[[ 0,  4],
        [ 1,  5],
        [ 2,  6],
        [ 3,  7]],

       [[ 8, 12],
        [ 9, 13],
        [10, 14],
        [11, 15]]])

3、通用函数:快速点对点数组函数

在我的理解中,点对点的意思就是单独处理数组中的每个元素

1、一元通用函数

就是只处理一个数组的

import numpy as np

arr = np.arange(10)
# array([0, 1, 2, 3, 4, 5, 6, 7, 8, 9])

np.sqrt(arr)
# array([ 0.        ,  1.        ,  1.41421356,  1.73205081,  2.        ,
#         2.23606798,  2.44948974,  2.64575131,  2.82842712,  3.        ])

np.exp(arr)
# array([  1.00000000e+00,   2.71828183e+00,   7.38905610e+00,
#          2.00855369e+01,   5.45981500e+01,   1.48413159e+02,
#          4.03428793e+02,   1.09663316e+03,   2.98095799e+03,
#          8.10308393e+03])

这些函数可以接受一个可选参数作为输出,如果是原数组,就可以直接修改原数组。

# 不会改变原数组 
np.sqrt(arr)
# 会改变原数组
np.sqrt(arr, arr)

常用一元函数

  • abs,fabs:计算整数,浮点数和复数的绝对值

  • sqrt: 平方根

  • square: 平方

  • exp: e**x

  • log,log10:

  • log2,logx:

  • sign:返回 -1, 0, 1

  • ceil:比元素大的数中最小的整数

  • floor: 比元素小的数中大的整数

  • rint:四舍五入

  • modf:

  • isnan:返回布尔值,判断是否是非数字

  • isfinite,isinf:

  • cos,cosh,sin:

  • sinh,tan,tanh:

  • arccos,arccosh:

等等

2、二院通用函数

  • np.maximum()

# 对比x,y较大的值返回
np.maximum(x, y)
  • np.modf()

# 返回两个数组,分别是小数部分,整数部分
remainder, whole_part = np.modf(arr)

二元通用函数

  • add:

  • subtract:第一个减第二个

  • multiply:

  • divide,floor_divide:

  • power:

  • maximun,fmax:

  • minimum,fmin:

  • mod:模

  • copysign:把第二个的符号复制到第一个

比较

  • greater,greater_equal:

  • less,less_equal:

  • equal,not_equal:

  • logical_and:

  • logical_or:

  • logical_xor:

4、数组导向编程

向量化的数组运算比纯python同等程度的运算快很多

0、np.meshgrid(方法)

meshgrid函数用两个坐标轴上的点在平面上画网格。

import numpy as np

m, n = (5, 3)
x = np.linspace(0, 1, m)
# array([ 0.  ,  0.25,  0.5 ,  0.75,  1.  ])
y = np.linspace(0, 1, n)
# array([ 0. ,  0.5,  1. ])
X, Y = np.meshgrid(x, y)
# X
# array([[ 0.  ,  0.25,  0.5 ,  0.75,  1.  ],
#        [ 0.  ,  0.25,  0.5 ,  0.75,  1.  ],
#        [ 0.  ,  0.25,  0.5 ,  0.75,  1.  ]])
# Y
# array([[ 0. ,  0. ,  0. ,  0. ,  0. ],
#        [ 0.5,  0.5,  0.5,  0.5,  0.5],
#        [ 1. ,  1. ,  1. ,  1. ,  1. ]])

np.linespace()方法很明显是将前面两个参数的距离按第三个参数的数值等分,然后得到一个数组。虽然我不知道np.meshgrid()到底什么意思,但它的效果就是把第一个数组的个数作为列数,然后把第二个数组的个数作为行数,然后把两个数组编程维度相同的矩阵,如上。

可以使用zip得到坐标点的数据

z = [i for i in zip(X.flat, Y.flat)]
 [(0.0, 0.0),
 (0.25, 0.0),
 (0.5, 0.0),
 (0.75, 0.0),
 (1.0, 0.0),
 (0.0, 0.5),
 (0.25, 0.5),
 (0.5, 0.5),
 (0.75, 0.5),
 (1.0, 0.5),
 (0.0, 1.0),
 (0.25, 1.0),
 (0.5, 1.0),
 (0.75, 1.0),
 (1.0, 1.0)]

0、开始运算

points = np.arange(-5, 5, 0.01)
# 这里我才注意到,arrange好像和linspace没什么差别啊
xs, ys = np.meshgrid(points, points)
z = np.sqrt(xs ** 2 + ys ** 2)

然后还可以把图像画出来

plt.imshow(z, cmap=plt.cm.gray)
plt.colorbar()
plt.title("Image plot of $\sqrt{x^2 + y^2}$ for a grid of values")
plt.show()

numpy.where函数是一个向量版的三相表达式,x if condition else y

xarr = np.array([1.1, 1.2, 1.3, 1.4, 1.5])
yarr = np.array([2.1, 2.2, 2.3, 2.4, 2.5])
cond = np.array([True, False, True, True, False])
result = [(x if c else y) for x, y, c in zip(xarr, yarr, cond)]
# [1.1000000000000001, 2.2000000000000002, 1.3, 1.3999999999999999, 2.5]

这样的缺点是处理较大数组时比较慢,其次是不能处理多维数组

result = np.where(cond, xarr, yarr)
# array([ 1.1,  2.2,  1.3,  1.4,  2.5])

np.where的第二和第三个参数不必是数组,

np.where(arr > 0, 2, -2)
np.where(arr > 0, 2, arr)

2、数学和统计方法

一些能计算统计值的数学函数能基于整个数组,或者沿着一个axis,比如sum,mean

arr = np.random.randn(5, 4)
array([[-1.53575656, -1.39268394, -1.02284353, -1.03165049],
       [ 0.53301867,  0.50258973, -0.49389656,  0.24610963],
       [ 0.95377174, -1.57268184,  0.42969986,  1.22912566],
       [ 0.73686692, -2.82328155,  0.48018497, -1.38046692],
       [ 0.94164808,  0.19599722, -0.88779738, -0.87556277]])

示例

arr.mean()
np.mean(arr)

mean或sum这样的函数能接受axis作为参数,返回结果的维度更少

arr.sum()
# 计算各列之间的平均值
arr.mean(axis=1)
# 计算各行总和
arr.sum(axis=0)

cumsum和cumprod不做汇总,而是产生一个中间结果的数组

arr = np.array([0, 1, 2, 3, 4, 5, 6, 7])
arr.cumsum()
# array([ 0,  1,  3,  6, 10, 15, 21, 28])

对于多维数组,累加函数返回的是同样大小的数组

arr = np.array([[0, 1, 2], [3, 4, 5], [6, 7, 8]])
arr
# array([[0, 1, 2],
#       [3, 4, 5],
#       [6, 7, 8]])
# 沿着行累加
arr.cumsum(axis=0) 
array([[ 0,  1,  2],
       [ 3,  5,  7],
       [ 9, 12, 15]])
# 沿着列累乘
arr.cumprod(axis=1) 
array([[  0,   0,   0],
       [  3,  12,  60],
       [  6,  42, 336]])

3、布尔数组的方法

sum可以用来计算布尔数组中有多少个true

arr = np.random.randn(100)
(arr > 0).sum()

还有any和all对布尔数组特别有用

bools = np.array([False, False, True, False])
# 数组中存ture就返回ture
bools.any()
# 数组中都是true才返回ture
boos.all()

4、排序

对于一维数组

arr = np.random.randn(6)
arr.sort()

多维数组可以按照axis排序

arr = np.random.randn(5,3)
arr.sort(1)

上面的方法会修改数组的顺序,如果使用np.sort()函数,则会生成一个新的排序后的结果。

5、唯一和其他集合逻辑

np.unique()返回不重复的值

names = np.array(['Bob', 'Joe', 'Will', 'Bob', 'Will', 'Joe', 'Joe'])
np.unique(names)
array(['Bob', 'Joe', 'Will'], dtype='<U4')

np.inld()测试一个数组的值是否在另一个数组里,返回布尔数组

values = np.array([6, 0, 0, 3, 2, 5, 6])
np.in1d(values, [2, 3, 6])
array([ True, False, False,  True,  True, False,  True], dtype=bool)

其他集合操作

  • intersectld(x,y):计算x和y中的重复元素

  • unionld(x, y):

  • setdiffld(x, y):

  • setxorld(x, y):

1、像数组操作一样表示逻辑条件

http://nbviewer.jupyter.org/github/LearnXu/pydata-notebook/tree/master/Chapter-04/
https://github.com/BrambleXu/pydata-notebook
https://www.jianshu.com/p/04d180d90a3f
https://blog.csdn.net/lanchunhui/article/details/50158975