数据分析(一) 【Python】

一、NumPy库

1.1 ndarray:NumPy库的心脏

整个 NumPy 库的基础是 ndarray对象,它是一种通同质元素组成的多维数组,元素数量是事先指定好的。

同质指的是,几乎所有元素的类型和大小都相同。

事实上,数据类型由另外一个叫做 dtype(data-type,数据类型)的NumPy对象来指定,每个ndarray只有一种dtype类型

数组的维数和元素数量 由 数组的型 (shape) 来确定,数组的型由N个正整数组成的元组来指定,元组的每个元素对应每一维大小。

数组的维统称为 轴 ( axes ) ,轴的数量被称为 秩( rank )

NumPy的另一个数组的特点是大小固定,也就是说创建数组时一旦指定好大小,就不会再发生改变

1.4 基本操作

1.4.1 算术运算符
import numpy as np
a = np.arange(4)

print(a)
print(a+4)
print(a*2)
print('******************')

# 这些运算符可以用于两个数组的运算。在NumPy中,这些运算符为 元素级
# 也就是说,只用于位置相同的元素之间,所得运算结果组成一个新的数组

b = np.arange(3,7)
print(b)
print(a+b)
print(a-b)
print(a*b)
print('******************')

# 此外,这些运算符还适用于返回值为NumPy数组的函数。
# 例如,你可以用数组a乘上数组b的正弦值或平方根

print(a*np.sin(b))
print(a*np.sqrt(b))
print('******************')

# 对于多维数组,这些运算符仍然是 元素级

A = np.arange(0,9).reshape(3,3)
print(A)
B = np.ones((3,3))
print(B)
print('A*B的结果为:')
print(A*B)

在这里插入图片描述

1.4.2 矩阵积

使用 * 号作为元素级运算符是 NumPy库比较奇怪的一点。事实上,在其它数据分析的工具中,* 在用于两个矩阵之间的运算时指的是 矩阵积。而 NumPy 用 dot() 函数表示这类乘法。

注意:它不是元素级的

在这里插入图片描述

import numpy as np
# 对于多维数组,这些运算符仍然是 元素级
A = np.arange(0,9).reshape(3,3)

print('矩阵A:')
print(A)
B = np.ones((3,3))

print('矩阵B:')
print(B)

print('A*B的结果为:')
print(A*B)

print('矩阵积另一种写法,使用dot()函数:')
print(A.dot(B))

print('****************')
print(np.dot(B,A)) 

在这里插入图片描述

1.4.3 自增自减运算
import numpy as np
a = np.arange(4)
print(a)

a -= 1
print(a)

a += 1
print(a)

a *= 2
print(a)

在这里插入图片描述

1.4.4 通用函数
import numpy as np
a = np.arange(1,5)

print(a)
print('************************************')

print(np.sqrt(a))
print('************************************')

print(np.log(a))
print('************************************')

print(np.sin(a))

在这里插入图片描述

1.4.5 聚合函数

聚合函数是指对一组值(比如一个数组)进行操作,返回一个单一值作为结果的函数。因而,求数组所有元素之和的函数就是聚合函数。

ndarray 类 实现了多个这样的函数

import numpy as np
a = np.array([3.3,4.5,1.2,5.7,0.3])

print(a.sum())
print('************************************')

print(a.min())
print('************************************')

print(a.max())
print('************************************')

print(a.mean())
print('*************************************')

print(a.std())

在这里插入图片描述

1.5 索引机制、切片 和 迭代方法

关于数组对象的操作方法,以及如何通过 索引 和 切片 方法选择元素,以获取数组中某几个元素的视图或者用赋值操作改变元素。

数组的迭代方法

1.5.1 索引机制

在这里插入图片描述
要获取数组的单个元素,指定元素的索引即可:

import numpy as np
a = np.arange(10,16)
print(a)
print(a[4])
print(a[-2])

在这里插入图片描述
NumPy数组还可以使用负数作为索引。这些索引同样为递增序列,只不过从0开始,依次增加-1,但实际表示的是从数组的最后一个元素向数组第一个元素移动。在负数索引机制中,数组第一个元素的索引最小

也可以同时传入多个索引值,同时选择多个元素:

import numpy as np
a = np.arange(10,16)

print(a[[-1,-2,0,1,2]])

在这里插入图片描述
再来看下:二维数组(也称 矩阵)。矩阵是由行和列组成的矩形数组,行和列用两条轴来定义,其中轴0用行表示,轴1用列表示。

所以,二维数组的索引用一对值来表示:第一个值为行索引,第二个值为列索引。

在这里插入图片描述

import numpy as np
a = np.arange(10,19).reshape(3,3)
print(a) 
print('______________')
print(a[1,1]) # 获取第二行、第二列的元素,需要使用索引值[1,1]

在这里插入图片描述

1.5.2 切片操作

切片操作 是指抽取数组的一部分元素生成新数组。对Python列表进行切片操作得到的数组是原数组的副本,而对NumPy数组进行切片操作得到的数组则是指向相同的缓冲区的视图

import numpy as np
a = np.arange(10,16)

print(a)
print('______________')

print(a[1:5])
print('______________') 

print(a[1:5:2])
print('______________')

# 省去第一个数字,NumPy会认为第一个数字是0(对应数组的第一个元素)
# 省去第二个数字,NumPy会认为第二个数字是数组的最大索引值
# 省去最后一个数字,将会被理解为1,就是抽取所有元素而不再考虑间隔

print(a[::2])
print('______________')

print(a[:5:2])
print('______________')

print(a[:5:])

在这里插入图片描述

对于二维数组,切句法依然适用,只不过需要分别指定 行 和 列 的索引

import numpy as np
a = np.arange(10,19).reshape(3,3)
print(a)

print('___第二个索引只使用冒号,没指定任何数字,这样选择的是所有列:____')
print(a[0,:])

print('___如果想抽取第一列的所有元素,方括号中的两项应该交换位置:____')
print(a[:,0])

print('___如果抽取一小点儿的矩阵,需要明确指定所有的抽取范围:____')
print(a[0:2,0:2])

print('___如果抽取的行或者列的索引不连续,可以把这几个索引放到数组中:____')
print(a[[0,2],0:2])

在这里插入图片描述

1.5.3 数组迭代

Python数组元素的迭代很简单,只需要使用 for结构 即可

import numpy as np
a = np.arange(10,19)
print(a)
for i in a:
    print(i)

在这里插入图片描述
二维数组也可以使用for结构,把两个嵌套在一起即可。第一行循环扫描数组的所有行,第二层循环扫描所有的列。

实际上,如果遍历矩阵,就会发现它总是按照第一条轴对矩阵进行扫描

import numpy as np
a = np.arange(10,19).reshape(3,3)
print(a)
for row in a:
   print('---------')
   print(row)

在这里插入图片描述
如果想遍历矩阵的每一个元素,可以使用下面结构,用 for循环 遍历 a.flat

import numpy as np
a = np.arange(10,19).reshape(3,3)
print(a)
for what_item in a.flat:
    print('---------')
    print(what_item)

在这里插入图片描述
除了 for循环,NumPy 还提供另外一种更为优雅的遍历方法:

通常用函数处理行、列 或者 单个元素时,需要用到遍历。

如果想要聚合函数处理每一列 或者 行,返回一个数值作为结果,最好用纯NumPy方法处理循环:apply_along_axis()函数

这个函数接收三个参数:聚合函数、对哪条轴应用迭代操作 和 数组

axis选项的值为0,按列进行迭代操作,处理元素;
axis选项的值为1,按行进行迭代操作。

import numpy as np
a = np.arange(10,19).reshape(3,3)
print(a)

print('********************')

b1 = np.apply_along_axis(np.mean,axis=0,arr=a)
print(b1)

print('********************')

b2 = np.apply_along_axis(np.mean,axis=1,arr=a) 
print(b2)

在这里插入图片描述
上面的例子使用了 NumPy库 定义的函数,但你也可以自己定义这样的函数。上面也使用了聚合函数,当然也可以用通用函数。

下面的例子,先后按行、列进行迭代操作,但两者的最终结果一致。
通用函数 apply_along_axis() 实际上是按照指定的轴逐元素遍历数组

import numpy as np
a = np.arange(1,10).reshape(3,3)

print(a)
print('----------------')

def foo(x):
  return x/2

b1 = np.apply_along_axis(foo,axis=1,arr=a)
print(b1)
print('*****************')

b2 = np.apply_along_axis(foo,axis=0,arr=a)
print(b2)

在这里插入图片描述

1.6 条件和布尔数组

另外一种从数组中有选择性的抽取元素的方法:使用条件表达式、布尔运算符

import numpy as np
a = np.random.random((4,4))
print('首先生成随机数组:')
print(a)
print('-----------------------')
print('然后对随机数组使用条件运算符,将会得到布尔值组成的数组:')
print(a<0.5)
print('-----------------------')
print('直接把条件表达式至于方括号中,也能抽取所有小于0.5的元素,组成一个新的数组:')
print(a[a<0.5])

在这里插入图片描述

1.7 形状变换

import numpy as np
a = np.random.random(12)
print('首先生成随机数组:')
print(a)
print('----reshape()函数返回一个新数组,因而可以用来创建新对象:------------')
A = a.reshape(3,4)
print(A)
print('----如果需要想通过变换数组的形状来改变数组对象,需要把表示新形状的元组直接赋给数组的shape属性----')
a.shape = (3,4)
print(a)
print('--------ravel()函数可以把二维数组再变回一维数组:---------')
a = a.ravel()
print(a)
print('-------甚至直接改变数组shape属性的值也可以:----------------')
a.shape = (12)
print(a)
print('----另一种重要的运算是,交换行列位置的矩阵转置----------------')
print(A.transpose())

在这里插入图片描述

1.8 数组操作

往往需要用已有数组创建新数组。

1.8.1 连接数组

把多个数组整合在一起形成一个包含这些数组的新数组。NumPy使用了栈这个概念。

  • vstack()函数执行垂直入栈操作,把第二个数组作为行添加到第一个数组,数组朝垂直方向生长
  • hstack()函数执行水平入栈操作,把第二个数组作为列添加到第一个数组
  import numpy as np
  a = np.ones((3,3))
  b = np.zeros((3,3))
  print(a)
  print(b)
  print('------vstack()函数:------')
  print(np.vstack((a,b)))
  print('------hstack()函数:------')
  print(np.hstack((a,b)))

在这里插入图片描述
还有两个用于数组之间栈操作的函数:

  • column_stack()
  • row_stack()

一般来讲,这两个函数把一位数组作为列 或者 行 压入栈结构,以形成一个新的二维数组

import numpy as np
a = np.array([0,1,2])
b = np.array([3,4,5])
c = np.array([6,7,8])

print('--------column_stack()函数:--------')
A = np.column_stack((a,b,c))
print(A)

print('--------row_stack()函数:--------')
B = np.row_stack((a,b,c))
print(B)

在这里插入图片描述

1.8.2 数组切分

逆操作:把一个数组分成几个部分。

split()函数复杂一点,可以把数组分为几个不对称的部分。

不仅将 传入数组作为参数,还 指定被切分部分的索引。

指定axis=1项,索引为列索引;如果axis=0,索引为行索引

for example,将矩阵切为三部分:第一部分为第一列,第二部分为第二列,第三部分为最后一列

import numpy as np
a = np.random.random(16).reshape(4,4)
[b,c,d] = np.split(a,[1,3],axis=1)
print('----------b---------')
print(b)
print('----------c---------')
print(c)
print('----------d---------')
print(d)
print('********也可以按行切分*********')
[b1,c1,d1] = np.split(a,[1,3],axis=0)
print('---------b1----------')
print(b1)
print('---------c1----------')
print(c1)
print('---------d1-----------')
print(d1)

在这里插入图片描述

在NumPy中,该操作要用到切分方法。

  • hsplit()函数:水平切分
  • vsplit()函数:垂直切分
  import numpy as np
  a = np.random.random(16).reshape(4,4)
  print('-----a-----')
  print(a)
  [b,c] = np.hsplit(a,2)
  print('-----b-----')
  print(b)
  print('-----c-----')
  print(c)
  print('********反之,vsplit()横着切一刀********')
  [c,d] = np.vsplit(a,2)
  print('------c-----')
  print(c)
  print('------d-----')
  print(d)

在这里插入图片描述

1.9 常用概念

介绍NumPy库的几个常用概念。副本和视图的区别,着重讲解两者返回值的不同。

还会介绍NumPy函数的很多事务(transaction)隐式使用的广播机制(broadcasting)

1.9.1 对象的副本 或 视图

NumPy中,无论在做数组运算,还是数组操作时,返回结果不是数组的副本,就是数组的视图。

NumPy中,所有赋值运算不会为数组和数组中的任何元素创建副本

1.9.2 向量化

向量化 和 广播 这两个概念是NumPy内部实现的基础。

有了向量化,编写代码时,不需要使用显式循环。向量化的应用使得代码看上去更简洁,可读性更强。向量化使得很多运算看上去更像数学表达式。

1.9.3 广播机制

广播机制这一操作实现了两个或两个以上数组进行运算或者用函数处理,即使这些数组形状并不完全相同。

广播机制的第二条规则:解释的是如何扩展最小的数组,使得它跟最大的数组大小相同,以便使用元素级的 函数 或者 运算符
在这里插入图片描述

import numpy as np
a = np.arange(4)
b = np.random.random(16).reshape(4,4)

print(a)
print(b)
print(a+b)

在这里插入图片描述

还有更复杂的情况:两个数组形状不同、维度不同、互有长短

import numpy as np
m = np.arange(6).reshape(3,1,2)
n = np.arange(6).reshape(3,2,1)
print('-------m-------')
print(m)
print('-------n-------')
print(n)
print('-------m+n------')
print(m+n)

这种情况下,两个数组都需要扩展维度(进行广播),然后就可以对两个数组进行诸如加法这样的元素级运算
在这里插入图片描述

1.10 结构化数组

1.11 数组数据文件的读写

NumPy这方面的内容很重要,用处很大,尤其是在处理数组中包含大量数据的情况时。这在数据分析中很常见,因为要分析的数据集通常都很大,所以由人工来管理这类事务的执行,以及接下来从一台或计算过程的一段会话读取数据到另一台计算机或另一段会话,是不可取的,甚至是不可能的。

因此,NumPy提供了几个函数,数据分析师可用其把结果保存到文本或者二进制文件中。

类似,NumPy还提供了从文件中读取数据并将其转换为数组的方法。

1.11.1 二进制文件的读写

NumPy 中,

  • save()方法 以二进制格式保存数据
  • load()方法 从二进制文件中读取数据
1.11.2 读取文件中的列表形式数据

一般的文件文本格式不是二进制的,而是例如:TXT、CSV(Comma-Separated Values,用逗号分割的值)的格式

import numpy as np
data = np.genfromtxt('dat.csv',delimiter=',',names=True)
print(data)

在这里插入图片描述
索引:
在这里插入图片描述


二、pandas 库

2.1 pandas数据结构简介

  • Series 对象(序列)
  • DataFrame 对象(数据框架)
  • Index 对象
2.1.1 Series对象

series 这类数据结构用于存储一个序列这样的一维数组,而 DataFrame 作为更重复的数据结构,则用于存储多维数据

虽然这些数据结构没法解决所有的问题,但是大多数应用提供了有效和强大的工具

1.声明Series对象
调用Series()构造函数,把要存放在Series对象中的数据以数组形式传入

import pandas as pd
s = pd.Series([12,-4,7,9],index=['a','b','c','d'])
print('-------s-------')
print(s)
print('-------s.values()-------')
print(s.values)
print('-------s.index()-------')
print(s.index)

在这里插入图片描述

import pandas as pd
data = pd.read_csv('D:\python_file\dat.csv')
print(data)
print('----打印前1行数据:------')
print(data.head(1))
print('----打印索引,3行4列------')
print(data.shape)
print('-----------------------')
print(data.info())
print('-----------------------')
print(data.describe())

在这里插入图片描述
2.选择内部元素

import pandas as pd
s = pd.Series([12,-4,7,9],index=['a','b','c','d'])
print('-------获取Series对象内部元素,s[2]------')
print(s[2])
print('-------指定索引位置处的标签------------')
print(s['b'])
print('-------选择多个元素,s[0:2]------')
print(s[0:2])
print('--------用元素对应的标签获取元素-----------')
print(s[['b','c']])

在这里插入图片描述
3.为元素赋值
可以用索引 或者 标签选取元素后进行赋值

import pandas as pd
s = pd.Series([12,-4,7,9],index=['a','b','c','d'])
print('-------0------')
print(s)
print('-------1------')
s[2] = 0
print(s)
print('-------2------')
s['b'] = 1
print(s)

在这里插入图片描述
4.用NumPy数组或其他Series对象定义新Series对象

 import numpy as np
 import pandas as pd
 s = pd.Series([12,-4,7,9],index=['a','b','c','d'])
 arr = np.array(([1,2,3,4]))
 s1 = pd.Series(arr)
 s2 = pd.Series(s)
 print(s1)
 print('--------------')
 print(s2)

在这里插入图片描述
新Series对象中的元素不是原NumPy数组或Series对象元素的副本,而是对它们的引用。

也就是说,这些对象是动态插入到新Series对象中

如改变原有对象元素的值,新Series对象中这些元素也会发生改变

5.筛选元素

import numpy as np
import pandas as pd
s = pd.Series([12,-4,7,9],index=['a','b','c','d'])
print(s[s>8])

a    12
d     9
dtype: int64

6.Series对象运算 和 数学函数
适用于NumPy数组的运算符(+、-、*、/)或 其它 数学函数,也适用于 Series对象。至于运算符,直接用来编写算术表达式即可

import numpy as np
import pandas as pd
s = pd.Series([12,-4,7,9],index=['a','b','c','d'])
A = s/2
print(A)
B = np.log(s)
print(B)

在这里插入图片描述
7.Series对象的组成元素
Series对象往往包含重复的元素,统计元素重复出现的次数 或 判断一个元素是否在 Series中

import numpy as np
import pandas as pd
s = pd.Series([1,0,2,1,2,3],index=['white','white','blue','green','green','yellow'])
print(s)
print('------s.unique()------')
print(s.unique())
print('------s.value_counts()------')
print(s.value_counts())
print('------isin()------')
print(s.isin([0,3]))
print(s[s.isin([0,3])])

在这里插入图片描述
8.NaN
数据结构中,若字段为空 或者 不符合数字的定义时,用这个特定的值来表示

创建数据结构时,可为数组中元素缺失的项输入 np.NaN

import numpy as np
import pandas as pd
s = pd.Series([1,0,np.NaN,1,2,3])
print(s)
print('------s.isnull()------')
print(s.isnull())
print('------s.notnull()------')
print(s.notnull())

上述两个函数返回两个由布尔值组成的 Series对象,对象中的元素是NaN时,isnull()函数返回值为True,notNull()函数返回False,反之,就都反了。
在这里插入图片描述
9.Series用作字典

import numpy as np
import pandas as pd
mydict = {'red':2000,'blue':1000,'yellow':500,'orange':1000}
mySeries = pd.Series(mydict)
print(mySeries)
print('-----------------')
colors = ['red','yellow','orange','blue','green']
mySeries1 = pd.Series(mydict,index=colors)
print(mySeries1)

在这里插入图片描述
10.Series对象之间的运算

Series这种数据结构在运算时有个优点,通过识别标签对齐不一致的数据

下面这个例子,求求只有部分元素标签相同的两个Series对象之和

import pandas as pd
mydict1 = {'red':2000,'blue':1000,'yellow':500,'orange':1000}
mydict2 = {'red':2000,'blue':1000,'yellow':500,'black':911}
mySeries1 = pd.Series(mydict1)
mySeries2 = pd.Series(mydict2)
print(mySeries1 + mySeries2)

在这里插入图片描述

2.1.2 DataFrame对象

与Series对象不同的是,DataFrame对象由一维扩展到多维,DataFrame对象按一定顺序排列的多列数据组成,各列数据类型可以有所不同(数值、字符串、布尔值 等)

1.定义DataFrame对象

import numpy as np
import pandas as pd
data = {'color':['blue','green','yellow','red','white'],
        'object':['ball','pen','pencil','paper','mug'],
        'price':[1.2,1.3,2.4,4.5,9.8]}

frame = pd.DataFrame(data)
print(frame)
frame1 = pd.DataFrame(data,columns=['object','price'])
print(frame1)

print('-----------------')
frame2 = pd.DataFrame(data,index=['one','two','three','four','five'])
print(frame2)

print('-----------------')
frame3 = pd.DataFrame(np.arange(16).reshape((4,4)),
                      index=['red','blue','yellow','white'],
                      columns=['ball','pen','pencil','paper'])
print(frame3)

在这里插入图片描述
2.选取元素

import pandas as pd
data = {'color':['blue','green','yellow','red','white'],
        'object':['ball','pen','pencil','paper','mug'],
        'price':[1.2,1.3,2.4,4.5,9.8]}

frame = pd.DataFrame(data)
print(frame.columns)
print(frame.index)
print(frame.values)
print(frame['price'])
print(frame.price)
print(frame.ix[[2,4]])
print(frame[0:1])
print(frame[1:3])
print(frame['object'][3])

3.赋值
依照相同的逻辑就能增加或修改元素

import pandas as pd
data = {'color':['blue','green','yellow','red','white'],
        'object':['ball','pen','pencil','paper','mug'],
        'price':[1.2,1.3,2.4,4.5,9.8]}

frame = pd.DataFrame(data)
frame.index.name = 'id'
frame.columns.name = 'item'
print(frame)
import pandas as pd
data = {'color':['blue','green','yellow','red','white'],
        'object':['ball','pen','pencil','paper','mug'],
        'price':[1.2,1.3,2.4,4.5,9.8]}

frame = pd.DataFrame(data)
frame['new'] = 12
print(frame)
import pandas as pd
data = {'color':['blue','green','yellow','red','white'],
        'object':['ball','pen','pencil','paper','mug'],
        'price':[1.2,1.3,2.4,4.5,9.8]}

frame = pd.DataFrame(data)
frame['new'] = [3.0,1.3,2.2,0.8,1.1]
print(frame)
import numpy as np
import pandas as pd
data = {'color':['blue','green','yellow','red','white'],
        'object':['ball','pen','pencil','paper','mug'],
        'price':[1.2,1.3,2.4,4.5,9.8]}

frame = pd.DataFrame(data)
ser = pd.Series(np.arange(5))
print(ser)
frame['new'] = ser
print(frame)
print('---------------')
frame['price'][2] = 3.3
print(frame)

4.元素的所属关系

5.删除一列

6.筛选

7.用嵌套字典生成 DataFrame 对象

import numpy as np
import pandas as pd
data = {'color':['blue','green','yellow','red','white'],
        'object':['ball','pen','pencil','paper','mug'],
        'price':[1.2,1.3,2.4,4.5,9.8]}


nestdict = {'red':{2012:22,2013:33},
            'white':{2011:13,2012:22,2013:16},
            'blue':{2011:17,2012:27,2013:18}}
frame = pd.DataFrame(nestdict)
print(frame)

8.DataFrame 转置

import pandas as pd
data = {'color':['blue','green','yellow','red','white'],
        'object':['ball','pen','pencil','paper','mug'],
        'price':[1.2,1.3,2.4,4.5,9.8]}

frame = pd.DataFrame(data)
print(frame.T)
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值