numpy & pandas

2018-10-06  本文已影响0人  零点有成MagicWars

一、安装与基本使用

进入jupyter

    # 生成一个array
    import array
    arr = array.array() 

但是,array仍然仅仅为一个集合,并不能做向量或矩阵的计算。因此需要使用numpy。

numpy中的ndarray

  import numpy as np
  nparr = np.array(range(10))
  nparr.dtype # 利用dtype 查看数据类型

在计算中如果需要浮点数,可以在初始化时使用带有浮点的初始值

  nparr1 = np.array([1, 2, 3.0])
  nparr1.dtype
  # 也可以在初始化时直接使用dtype指定数据类型
  nparr2= np.array(list(range(5)), dtype=float)
  nparr2.dtype

正常情况下,numpy可以自动选择数据类型。

numpy 的简单使用与性能测试

  import numpy as np
  def numpy_test(n):
          a = np.arange(n) ** 2
          b = np.arange(n) ** 3
          c = a + b
          return c
   numpy_test(10)
    %timeit numpy_test(10000000)

二、numpy中的矩阵和随机数生成

生成等差数列

  np.linspace(初始值, 结束值, 截取数据点数)
  np.linspace(0, 20, 11)
  # 若不包含20,可以使用
  np.linspace(0, 20, 11, endpoint=False)

利用一个元素去填充矩阵

  np.full((3, 5), 0.99)
   np.full((3, 5), fill_value=0.99)

生成随机数

    np.random.randint(0, 10)
    np.random.randint(0, 10, size=5) # 生成5个随机数
    np.random.randint(0, 10, size=(2,5)) # 生成2行5列的随机数

计算机生成的随机数均为伪随机数。随机数的生成依赖随机种子。为了获取相同的随机结果,可以在每次生成随机数前,设置随机数的种子。

    np.random.seed(100)
    np.random.randint(0, 10, 3)
    np.random.random((元组)) # 生成X行X列浮点数
    np.random.normal(均值, 标准差, size=(元组))

二、ndarray基础操作

使用ndim,shape,size来查看

   a = np.arange(10)
    a.ndim # 查看维度
    a.shape # 查看属性
    a.size #

利用reshape来改变

  a = np.arange(10)
  a.reshape(行数,列数) # a变成了2行5列的数组
  a.reshape(行数,-1) # 使用-1时numpy会自动计算列数

数组切片的使用
a[0:8:2] # 以间隔2取值
二维数组的操作

    X[0:2, 0:3] # 取出前2行前3列的数组
    X[:2, 0::2] # 在前2行中间隔1列进行取值
    X[::-1, ::-1] # 取出所有行列,但行列顺序进行颠倒

切片所获取的新变量与原变量之间有引用关系
python列表切片所获取的新变量与原变量之间没有关系,而numpy中数组则有引用关系

  a = np.arange(15)
  x = a.reshape(3, -1)
  x2 = x[::2, ::2]
  x2[0, 0] = 99

如若需要新变量脱离与原变量的引用关系,则需要调用copy()方法

  x3 = x[:2, :2].copy()

三、数组的合并与分割

四、矩阵运算

加减乘除
np.abs()
np.sin()
np.cos()
np.tan()
np.exp() # 以e为底
np.power(3, x) # 以3为底
np.log10(X)

矩阵与矩阵的运算

    a = np.arange(4).reshape(2, -1)
    b = np.full((2, 2), 10)

numpy中的加减乘除都是对应元素作相应运算。

要做标准矩阵的乘法运算,可以使用dot()

    a.dot(b)

矩阵的逆

    A = np.arange(4).reshape(2, -1)
    invA = np.linalg.inv(A)

矩阵的转置

    A.T

五、聚合操作

    np.sum(X)
    np.min(X)

对于二维数组求和时,

    np.sum(X, axis=0) # 求垂直一列上的和
    np.sum(X, axis=1) # 求水平一行上的和
    np.prod(X) # 所有数相乘
    np.mean(X, axis=)
    np.median(X)
    np.percentile(X, q=50)
    np.var(X) # 求方差
    np.std(X) # 求标准差

numpy中的arg运算

七、numpy中的比较运算

对于二维数组

    row = [0, 2, 4]
    col = [1, 3, 4]
    x[row, col]
    x[1:3, col]

提取第2行中能被2整除的列

  y = np.arange(16).reshape(4, -1)
  ind = y[1, :] % 2 == 0
  y[:, ind]

八、pandas的安装与数据结构

Series可以将字典中的key自动作为索引,也可以将series转为字典或列表

    data = {'beijing': 10000, 'shanghai': 9999}
    ser = pd.Series(data, index=['shanghai', 'Shenzhen'])
    ser.to_dict() # 将ser转化为字典
    ser.to_list() # key会被丢掉
    ser.to_json()
    ser.to_frame()

九、pandas对数据的选取操作

  data = {
          'name': ['张三', '李四', '钱二', '孙六'],
          'age': [20, 24, 25, 23],
        'height': [168, 179, 164, 170],
  }
  df = pd.DataFrame(data, columns=['name', 'age', 'height'])
  df['name']
  df.age
  df[['age', 'name']]
  names = df.name 
  names[1] = '周七' # 此时原数据data也被修改
  ages = df.age.copy()
  ages[2] = 28 # 此时原数据data不会被修改

  ind = df.columns[1:2] 
  df[ind] #获取第2列数据

通过以上数据计算出生年份

 import datetime

df['year'] = datetime.datetime.now().year - df.age
df

删除列

 df.drop('year', axis=1)
 df.drop(df.columns[2:3], axis=1)

以行的角度截取数据,返回的是Series

  df.loc[2] # 获取第3行所有数据

如果要返回dataframe格式的数据,则需要使用列表

  df.loc[[1, 3]] # 这里的1到3指的是index中的行名称,而不是第几行。如果中间有缺失就会报错

可以使用整数获取行,要仔细区别loc[]和iloc[]的区别

  df.iloc[2] # 获取第3行的数据,可以不受index限制
  df.iat[1, 1] # 获取第2行第列中的数据

  df.index  # 默认为整数序列
  ind = df.index[-2:]
  df.loc[ind2] # 等同于df[-2:]  ; # 不加冒号等同于取列

增加一行数据

  df.shape
  df.loc[df.shape[0]] = {'name': '吴十一', 'age': 29, 'height': 172, 'year': 1989}

删除行

  df.drop()

筛选数据

  ind5 = df.height >= 170
  ind6 = df.age > 25
  df[ind5]
  df[(ind5) & (ind6)]

  df.query('height>=170 and age>25') 
  df.query('height>=170 and age>25 or name=="吴十一"') 

  #   query同时支持变量查询
  age = 27
  df.query('age >= @age')

  # 指定搜索
  df[df.age.isin([19, 25])]

十、pandas加载数据

很多情况下一行包含多个信息,如果使用read_table正确加载,需要标题之间不使用空格,而是tab。
可以手动指定分隔符

  pd.read_table('<path>/<filename>.txt', sep=':', header=None) # 同时指定没有标题行
 pd.read_table('<path>/<filename>.txt', sep=':', names=['ID', 'info'], parse_dates = ['created_at']) # 如果含有时间序列,则需要指定解析某一列为时间

也可以通过指定表格属性

    pd.read_html('<filename>.html', header=0, attrs={'class': 'mydata'})

十、Pandas合并与排序

应当注意,当使用values排序时,None永远排在最后。
二维数组排序
  arr = [[9 ,4, 8],
         [4, 6, 7],
         [4, 5, 3]]
  df= pd.DataFrame(arr, index=[0, 2, 1], columns=list('cab'))
  df.sort_index() # 按照索引排序
  df.sort_index(axis=1)   # 按照列排序(需要指定轴)

十一、Pandas的数据汇总

    data = [[1, None, ],
                [4, 5],
                [None, None],
                [8, 9],
                [7, 3],
                [2, 9],]
  df = pd.DataFrame(data, columns=['a', 'b'])
  df.head # 显示前5行
  df.head(2) # 显示前2行
  df.tail(3) # 显示后3行
  df.info() # 查看当前dataframe的基本信息

  df.describe() # 显示数据的多项信息,包括数量、平均值、方差、四分位数等
  df.sum()
  df.a.sum() # a列求和
  df.cusum() # 累加求和,显示一行与前面所有行的值的总和
  df.count()
  df.var() # 求方差

十二、 pandas中的数据分组与透视表

每一列显示的数据类型不同,如单价显示平均值,而数量显示总和

    # 默认条件下pivot_table均是求平均值
    z = df.pivot_table(index=['类别', '名称'], values=['单价', '数量'])

    # 如若需要对数量求和,则
    z = df.pivot_table(index=['类别', '名称'], values=['单价', '数量'])

十三、pandas中的时间序列

在data_range中,默认(M)为月,W为周,Q为季度,H为小时,T为分钟,S为秒,D为天,A为年

    pd.data_range('2018-10-1', '2018-10-31', freq='w') # 生成时间序列

    pd.data_range('2018-10-1', freq='Q', peridos=10) # 以季度为周期,返回10个季度的时间间隔

要取出某一时间段内的数据,则

      df[(df.time>='2018-11-10 10:00:00') & df.time<='2018-11-13 23:00:00']

需要增大采样时间间隔,则先利用set_index将时间作为索引

    df.set_index('time')

这时就可以利用切片获取时间

     df2['2018-11-10 10:00:00':'2018-11-13 23:00:00']

也可以直接给定一个日期,获取该天内所有监控数据

    df2['2018-11-9']

也可以利用groupby进行分组

    df2.groupby(df2.index.date).mean() # 获取每天的平均值
     df2.groupby(df2.index.hour).mean() # 获取每小时的平均值

在上述例子中,原始数据为每隔1min取样,利用resample可以改变采样间隔

    df2.resample('90S').mean() #每间隔90s进行采样,取平均值、最大值、最小值取决于实际需要

十四、pandas中的时间序列

本节主要讲matplotlib的使用,但我更喜欢pyecharts,所以相关的学习在官网手册中开展。
http://pyecharts.org/#/

十五、数据质量和特征分析及数据清洗

在爬虫等数据获取过程中,要考虑样本的数量或质量是否满足要求,样本之间有无关联性。探索性数据分析包括数据质量分析和数据特征分析

检查是否存在脏数据

1. 缺失值
    df.isnull() # 当数据为空(NaN)时,显示True
    df.isnull().sum() # 数据为空的个数
2. 异常值
  df.describe()
  (df['年龄']>=16) | (df['年龄']<=30) # 可以通过对年龄段的筛选来获取异常值,异常值显示为False
3. 重复值
    df.duplicated() # 只当两条数据全部一样时,才会返回True
    df.duplicated(subset=['姓名']) # 当姓名一致时,才会返回True
4. 一致性

在实际分析过程中,可能会存在数据更新后结果不一致,叫法或写法不同的现象,都需要对数据做进一步的处理。

    df['语言'].unique() 
1.分布分析
2. 对比分析
3. 周期分析
4. 贡献度分析
5. 相关性分析
    import seaborn as  sns
    corr = df.corr()
    sns.heatmap(corr)
    plt.show()
1. 缺失值处理
    df.dropna() # 默认有1个数据为空,则本条数据被丢弃

可以指定丢弃数据方式

    df.dropna(how='all') # 当所有数据为空时,本条数据才会被丢弃

也可以针对某一列进行数据丢弃

    df.dropna(subset=['salary']) # 本列中数据为空的数据会被丢弃

当数据缺失较多时,应当做填充处理

    df.fillna(values)

不同的列可以填充不同的值,可以

    df.fillna({'age':18, 'language':'nothing'})

pandas中有更高级的填充方式

    df.fillna(method='ffill') # ffill 表示将前面一个样本的值赋给该样本 frontfill
    df.fillna(method='bfill') # bfill 表示将前面一个样本的值赋给该样本 backfill
    df.fillna(method='ffill') # ffill 表示将前面一个样本的值赋给该样本 frontfill

也可以使用差值函数

    df.interpolate()

对于不是数值型的数据,大多数情况下使用固定值来进行标注

    df.fillna({'language': 'missing'})
    df.fillna({'language': 'missing'}, limit=2) # 加上limit可以限定填充个数
2. 异常值处理

获取上下四分位数,然后获取上下四分位数的间距range

    q_upper = df.age.quantile(0.75)
    q_lower = df.age.quantile(0.25)
    range = q_upper - q_lower 

设置一个系数,一般取1.5~3

    k = 1.5

然后获取上下四分位1.5倍间距以内的所有数值

    ind = (df.age<=q_upper +k*range) & (df.age>=q_lower-k*range)
    df2 = df[]
3. 重复值处理

最直接的方式是丢弃处理

    df.drop_duplicates() # 默认所有字段全部相同时,方才删除重复值

也可以利用字段来删除
df.drop_duplicates(['age', 'salary'])

上一篇 下一篇

猜你喜欢

热点阅读