python

day77-数据分析之numpy

2019-03-05  本文已影响30人  barriers

numpy是数据分析中最基础的分析库,而numpy中最重要的部分是np.array

1numpy库

1.1利用数组进行数据处理

np.meshgrid函数接受两个一维数组,并产⽣生两个二维矩阵(对应于两个数组中所有的(x,y)

points = np.arange(-5, 5, 0.01) 
xs, ys = np.meshgrid(points, points) 
z = np.sqrt(xs ** 2 + ys ** 2)

points = np.arange(-5, 5, 0.01) 表示生成从-5到5,步长为0.01的1000个数。
上面xs将把points按行重复1000遍(即每行内容相同);ys将把points按列重复1000遍(即每列内容相同);np.sqrt(xs ** 2 + ys ** 2)表示对两个数平方在开方。
二维数组的可视化

%matplotlib#把matplotlib放入后台运行
import matplotlib.pyplot as plt
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()

1.2将条件逻辑表述为数组运算

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 = np.where(cond, xarr, yarr)

上面表示当cond中的值为True时,选取xarr的值,否则从yarr中选取
np.where(arr > 0, 2, -2) 将arr中大于0的换为2,不大于0的变为-2
np.where(arr > 0, 2, arr) 将arr中大于0的换为2,不大于0的不变

1.3数学和统计方法

可以通过数组上的一组数学函数对整个数组或某个轴向的数据进行统计算。sum(求和)、mean(求平均值)以 及标准差std等聚合计算(aggregation,通常叫做约简(reduction))
arr.mean(1)是“计算行的平均值”,arr.sum(0)是“计算每列的和”
arr.cumsum(axis=0) 计算每列累加的和;arr.cumprod(axis=1) 计算每行累积的和

bools = np.array([False, False, True, False])
bools.any() 
bools.all() 

any用于测试数组中是否存在一个或多个True,而all则检查数组中所有值是否都是True, 这两个方法也能用于非布尔型数组,所有非0元素将会被当做True。

1.4排序

arr = np.random.randn(6)
arr.sort()
arr.sort(1) # 对行进行升序排序
np.sort(arr,0) # 对arr进行按列排序

arr.sort() 对arr进行升序排序,会修改arr;就地排序会修改数组。
np.sort(arr,0)对arr进行按列排序,不会修改arr;返回的是数组的已排序副本

1.5数组的唯一化

ints = np.array([3, 3, 3, 2, 2, 1, 1])
np.unique(ints) 

np.unique(names) 找出数组中的唯一值并返回已排序的结果

1.6检查一个数组中的值是否在另一个数组中

函数np.in1d用于测试一个数组中的值是否在另一个数组中,返回一个布尔型数组

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

intersect1d(x,y)计算x和y中的公共元素,返回有序结果;union1d(x,y)计算x和y的并集,返回有序结果;setdiff1d(x,y)集合的差,即元素在x中,不在y中;

1.7数组的文件输入输出

np.save和np.load是读写磁盘数组数据的两个主要函数。默认情况下,数组是以未压缩的原始二进制格式保存在扩展名为.npy的文件中的

arr = np.arange(10)
np.save('some_array', arr) # 保存arr为some_array文件
np.load('some_array.npy')  # 打开文件

通过np.savez可以将多个数组保存到一个未压缩文件中

np.savez('array_archive.npz', a=arr, b=arr)
arch = np.load('array_archive.npz')
arch['b'] 

将数据压缩,可以使用numpy.savez_compressed

np.savez_compressed('arrays_compressed.npz', a=arr, b=arr)

1.8线性代数

矩阵乘法的dot函数

x = np.array([[1., 2., 3.], [4., 5., 6.]])
y = np.array([[6., 23.], [-1, 7], [8, 9]])
x.dot(y)  #[[  28.,   64.],[  67.,  181.]]

一个二维数组跟一个大小合适的一维数组的矩阵点积运算之后将会得到一个一维数组。
@符也可以用作中缀运算符,进行矩阵乘法

x @ np.ones(3) #[  6.,  15.]

1.9伪随机数生成

用normal来得到一个标准正态分布的4×4样本数组

samples = np.random.normal(size=(4, 4))

Python内置的random模块则只能一次生成一个样本值。从下面的测试结果中可以看出,如果需要产生大量样本值,numpy.random快了了不止一个数量级。
numpy.random的数据生成函数使用了全局的随机种子。要避免全局状态,你可以使用numpy.random.RandomState,创建一个与其它隔离的随机数生成器。

rng = np.random.RandomState(1234)
rng.randn(10) 

部分numpy.random函数说明
seed 确定随机数生成器的种子;rand 产生均匀分布的样本值;从给定的上下范围内随机选取整数;randn产生标准正态分布的样本值;binomial产生二项分布的样本值;normal产生正态分布的样本值;uniform产生在[0,1]中均匀分布的样本值。
用np.random模块一次性随机产生1000个“掷硬币”结果(即两个数中任选一个),将其分别设置为1或-1,然后计算累计和。

nsteps = 1000
draws = np.random.randint(0, 2, size=nsteps)
steps = np.where(draws > 0, 1, -1)
walk = steps.cumsum()
walk.min() 
walk.max() 

2pandas的使用

pandas是专门为处理表格和混杂数据设计的,而NumPy更适合处理统一的数值数组数据。pandas拥有两个主要数据结构:Series和DataFrame
Series是一种类似于一维数组的对象,它由一组数据(各种NumPy数据类型)以及
一组与之相关的数据标签(即索引)组成

import pandas as pd
obj = pd.Series([4, 7, -5, 3])

创建Series时不设置index索引,默认从0开始步长为1;用于对各个数据点进行标记;也可以对其进行设置索引

obj2 = pd.Series([4, 7, -5, 3], index=['d', 'b', 'a', 'c'])
obj2.index 
obj2.values 
obj2['a']  # 获取索引为a的值
obj2[['c', 'a', 'd']] # 一次索引多个值
obj2[obj2 > 0]  # 筛选出大于0的值
obj2 * 2 # 将值各乘2
'b' in obj2  # 查看索引b是否在obj2中

通过字典创建series及利用索引改变顺序

sdata = {'Ohio': 35000, 'Texas': 71000, 'Oregon': 16000, 'Utah': 5000}
obj3 = pd.Series(sdata)
states = ['California', 'Ohio', 'Oregon', 'Texas']
pd.Series(sdata, index=states) # 将重新排序的索引传入改变数据顺序

NaN(即“非数字”(not a number),在pandas中,它用于表示缺失或NA值)
pandas的isnull和notnull函数可用于检测缺失数据

pd.isnull(obj4) # 查看是否有数据为NAN(缺失)
pd.notnull(obj4) # 查看是否没有数据为NAN

Series最重要的一个功能是,它会根据运算的索引标签自动对齐数据

2.1series的name属性

Series对象本身及其索引都有一个name属性

obj4.name = 'population' # 给obj4命名为name(显示时在最后显示name为population)
obj4.index.name = 'state' #给索引赋name为state(索引的最上面)

Series的索引可以通过赋值的方式就地修改

obj.index = ['Bob', 'Steve', 'Jeff', 'Ryan'] # 给obj的索引重新赋值

2.2DataFrame使用

DataFrame是一个表格型的数据结构,它含有一组有序的列,每列可以是不同的值类型(数值、字符串、布尔值等),DataFrame既有行索引也有列索引。
建DataFrame, 传入一个由等长列表或NumPy数组组成的字典

data = {'state': ['Ohio', 'Ohio', 'Ohio', 'Nevada', 'Nevada', 'Nevada'], 
               'year': [2000, 2001, 2002, 2001, 2002, 2003], 
             'pop': [1.5, 1.7, 3.6, 2.4, 2.9, 3.2]} 
frame = pd.DataFrame(data) # 新建一个6行3列的数据
frame.head() 

特别大的DataFrame,head方法会自动选取前五行;如果指定了了列序列,则DataFrame的列就会按照指定顺序进行排列。

pd.DataFrame(data, columns=['year', 'state', 'pop']) 
frame2 = pd.DataFrame(data, columns=['year', 'state', 'pop', 'debt'],
          index=['one', 'two', 'three', 'four', 'five', 'six'])
frame2.columns # 取columns中的列名

上面表示新建一个行名为index中的参数,列名为columns中的参数的数组
将DataFrame的某列获取出来成为一个Series

frame2['state'] 

行也可以通过位置或名称的方式获取为一个单独series

frame2.loc['three'] 

给”debt”列赋上一个标量值或一组值

frame2['debt'] = 16.5
frame2['debt'] = np.arange(6)

如果赋值的是一个Series,就会精确匹配DataFrame的索引,所有的空位都将被填上缺失值

val = pd.Series([-1.2, -1.5, -1.7], index=['two', 'four', 'five'])
frame2['debt'] = val

为不存在的列赋值会创建出一个新列。关键字del用于删除列。

frame2['eastern'] = frame2.state == 'Ohio' # 为ohio的赋值为true
del frame2['eastern'] # 删除列

如果嵌套字典传给DataFrame,pandas就会被解释为:外层字典的键作为列,内层键则作为行索引。

pop = {'Nevada': {2001: 2.4, 2002: 2.9}, 
             'Ohio': {2000: 1.5, 2001: 1.7, 2002: 3.6}}
frame3 = pd.DataFrame(pop) # 没有值的就为NaN

2.3对DataFrame进行转置

对DataFrame进行转置(交换行列)使用T进行转置;设置了DataFrame的index和columns的name属性,则这些信息也会被显示出来(被转置)

frame3.T 
frame3.index.name = 'year'; frame3.columns.name = 'state'

values属性也会以二维ndarray的形式返回DataFrame中的数据

frame3.values # array([[ nan,  1.5],  [ 2.4,  1.7], [ 2.9,  3.6]])

如果DataFrame各列的数据类型不同,则值数组的dtype就会选用能兼容所有列的数据类型:

上一篇下一篇

猜你喜欢

热点阅读