首页 > 编程语言 > 详细

python数据分析三剑客

时间:2019-09-25 17:44:04      阅读:88      评论:0      收藏:0      [点我收藏+]

前言
大数据时代,数据的重要性不言而喻,掌握数据者得天下。很多同学可能对一堆数据不知如何进行处理分析得到有用的信息,本文主要基于anaconda 简单介绍 Numpy 模块的使用,重点演示 Pandas 的应用。
数据分析:把隐藏在一些看似杂乱无章的数据背后的信息提炼出来,总结出所研究对象的内在规律
数据分析三剑客:Numpy,Pandas,Matplotlib
Numpy与Padas是数据结构、Matplotlib绘图使用

  1. 环境准备

    环境变量 for zsh,并为 anaconda 的pip命别名

    export PATH=$PATH:/Applications/anaconda3/bin
    alias cpip="/Applications/anaconda3/bin/pip"
    source ~/.zhsrc
  2. numpy
    NumPy(Numerical Python):Python语言的一个扩展程序库,支持大量的维度数据与矩阵运算,针对数组提供大量的数学函数库。
  3. 使用np.array()创建
    数组
    import numpy as np

    一维数组

    np.array([1,2,3])

    二维数组

    np.array([[1,2,3], [4,5,6]])

    返回值优先级:str > float > int

    matplotlib绘图
    import matplotlib.pylab as plt

    返回一个数组,图片是三维数据

    img_arr = plt.imread(‘./cat.jpg‘)
    plt.imshow(img_arr)
    plt.imshow(img_arr-100)
  4. np的数组(4)
    linspace

    平均生成 num 个 start-stop数据

    np.linspace(start, stop, num)
    arange:等差数列

    start 默认是 0, step默认是 1, 给定 step 必须有start

    np.arange([start,] stop[, step,], dtype=None)

    不包含 10

    np.arange(0, 10, 2)
    random.randint():随机数

    [low, high),high=None表示 [0-low), size=(1,2,3...)表示维度

    np.random.randint(randint(low, high=None, size=None, dtype=‘l‘)

    固定随机性,随机因子(系统时间)

    np.random.seed(10)
    np.random.randint(0,100, size=(4,5))
    random.random(size)

    默认大小是 0-1

    np.random.random(size=(4,5))
  5. ndarray属性(3)
    arr.shape # (4,5),返回的是数组的形状
    arr.size # 元素个数
    arr.dtype # (‘int64‘),数据类型
  6. 操作(4)
    索引
    arr[1] # 第一个元素,索引从 0 开始
    arr[2, 3] # 第二行第三列元素
    切片
    arr[0:2] # 前两行
    arr[:, 0:2] # , 左边是行,右边是列
    arr[::-1] # 行倒序
    arr[:, ::-1] # 列倒序
    arr[:, ::-1, :]
    变形:参数是一个tuple
    arr.reshape()

    容量必须刚刚好

    arr.reshape((20,))
    arr.reshape((1, 20))
    arr.reshape(1, 20)

    自动计算行数

    arr.reshape((-1, 4))
    级联
    数据的拼接,注意行或列的长度

    axis=0 表示作用于行(纵向拼接),axis=1作用于列(横向拼接)

    np.concatenate((arr, arr), axis=0)
    算术运算
    广播机制:如果两个数组的后缘维度(从末尾开始算起的维度)的轴长度相符或其中一方的长度为1,则认为它们是广播兼容的。广播会在缺失维度和(或)轴长度为1的维度上进行。
    b = np.array([[1],[2],[3]])
    a = np.array([1,2,3])
    b-a
    --> array([[ 0, -1, -2],
    [ 1, 0, -1],
    [ 2, 1, 0]])
  7. ndarray聚合
    np.sum/mean
    arr.sum(axis=None) # 计算所有元素的和
    arr.sum(axis=0) # 作用于列,数据并到一行。列的和
    arr.sum(axis=1) # 作用于行,数据并到一列。行的和
    arr.mean(axis=None/0/1) # 平均数
    其他
    np.sqrt(arr) # 开方
    np.prod(arr) # 所有元素相乘
    np.min(arr) # 最小值
    np.max(arr) # 最大值
    np.std(arr) # 标准差
    np.var(arr) # 方差
    np.median(arr) # 中数
    np.power(arr,2) # 幂运算
    np.argmin(arr) # 最小值的下标
    np.argmax(arr) # 最大值的下标
    np.inf # 无穷大
    np.exp(10) # 以e为底的指数,e**10
    np.log(10) # 对数,e为底
  8. ndarray排序
    sort排序

    axis默认-1:表示按照上次的排序规则排序

    axis=0:表示按照列元素排序,1表示行元素排序

    np.sort(arr, axis=-1, kind=‘quicksort‘, order=None)

列元素排序,列有序,arr被修改

arr.sort(axis=0)

列元素排序,列有序,不改变原数据

np.sort(arr, axis=0)
Note(2)
axis=0:表示针对行进行计算或排序,列有序
axis=1:表示针对列进行计算或排序,行有序

  1. pandas
    ? SQL中的select是根据列的名称来选取;Pandas则更为灵活,不但可根据列名称选取,还可以根据列所在的position(数字,在第几行第几列,注意pandas行列的position是从0开始)选取。相关函数如下:

loc # 基于列label,可选取特定行(根据行index)
iloc # 基于行/列的position(默认的索引,整型)
at # 根据指定行index及列label,快速定位DataFrame的元素
iat # 与at类似,不同的是根据position来定位的
ix # 为loc与iloc的混合体,既支持label也支持position
导入需要的包
import pandas as pd
from pandas import Series, DataFrame
import numpy as np

  1. Series
  2. 创建和去重
    是一种类似与一维数组的对象
    values:一组数据(ndarray类型)
    index:相关的数据索引标签
    创建:由列表或numpy数组创建
    默认索引为0到N-1的整数型索引
    一定是一维的数据结构
    隐式索引和显示索引可以共存
    Series(data=[1,2,3]) # 隐式索引
    Series(data=[1,2,3], index=[a,b,c]) # 显示索引,提高可读性
    Series(data=np.random.randint(0,100, size=(4)))
    s = Series(data=[1,1,1,2,3,4,5,5,6])

    去重

    s.unique()

    NaN表示空,浮点类型

    运算:只能针对索引对齐的数据运算,否则为NaN

    空值检测

    pd.isnull(arr) 或 s.isnull()
    pd.notnull(arr) 或 s.notnull()
    s[[True, True, False, False]]
    s[s.notnull()] # 空值过滤
  3. Series的索引
    可以使用中括号取单个索引(此时返回的是元素类型),或者中括号里一个列表取多个索引(此时返回的是一个Series类型)。
    显式索引
    使用index中的元素作为索引值
    使用s.loc[](推荐):注意,loc中括号中放置的一定是显示索引
    注意,此时是闭区间
    s = Series([1,2,3,4], index=[‘a‘, ‘b‘, ‘c‘, ‘d‘])
    隐式索引
    使用整数作为索引值
    使用s.iloc[](推荐)s:iloc中的中括号中必须放置隐式索引
    注意,此时是半开区间
    s = Series([1,2,3,4])
  4. 切片:隐式索引和显示索引切片
    显示索引切片:index和loc
    s[‘a‘:‘b‘] # [‘a‘, ‘b‘]
    s.loc[‘a‘:‘b‘]
    隐式索引:iloc
    s[0:3] # [0, 3)
    s.iloc[0:3]
  5. Series基本概念
    可以通过shape,size,index,values等得到series的属性
    s.index # 索引
    s.values # 值
    s.size # 长度
    s.shape # (n,)
    可以使用s.head(),tail()分别查看前n个和后n个值,head默认为 5
    s.head(2)
    s.tail(2)
    去重
    s.unique()
    Series的运算:索引一致则相加,不一致则为Na

    + - * /

    add() sub() mul() div()

s1 + s2, 索引相同则相加,不同则保留切 +fill_value(float类型)

s1.add(s2,fill_value=0)
s1.mul(s2,fill_value=1)
Note(2)
默认格式:dtype: int64
Series之间的运算,自动对齐不同索引的数据,如果索引不对应,则补NaN

  1. DataFrame
  2. DataFrame简介
    DataFrame是一个【表格型】的数据结构。DataFrame由按一定顺序排列的多列数据组成。设计初衷是将Series的使用场景从一维拓展到多维。DataFrame既有行索引,也有列索引。
    行索引:index
    列索引:columns
    值:values
  3. 创建DataFrame
    最常用的方法是传递一个字典来创建。DataFrame以字典的键作为每一【列】的名称,以字典的值(一个数组)作为每一列。
    此外,DataFrame会自动加上每一行的索引。
    使用字典创建的DataFrame后,则columns参数将不可被使用。
    同Series一样,若传入的列与字典的键不匹配,则相应的值为NaN。

    使用ndarray创建DataFrame

    df = DataFrame(data=np.random.randint(0,100, size=(3,3)), index=(‘a‘, ‘b‘, ‘c‘), columns=(‘1‘, ‘2‘, ‘3‘))

使用 dic 创建DataFrame

dic = {
‘张三‘:[11,22,33,44],
‘李四‘:[55,66,77,88]
}
df_score = DataFrame(data=dic,index=[‘语文‘,‘数学‘,‘英语‘,‘理综‘])

属性:shape、index、colums、values

df.shape / .index /.colums /.vlues

  1. DataFrame的索引
    数据准备
    df=DataFrame(np.random.randint(0,100, size=(3,3)), index=(‘a‘,‘b‘,‘c‘), columns=(‘A‘,‘B‘,‘C‘))
    对列进行索引(2)
    通过类似字典的方式 df[‘q‘]
    通过属性的方式 df.q
    可以将DataFrame的列获取为一个Series。返回的Series拥有原DataFrame相同的索引,且name属性也已经设置好了,就是相应的列名。
    df.A / df[‘A‘] # 取一列,即一个 Series对象
    df[[‘A‘, ‘B‘]] # 取 A、B两列
    对行进行索引(2)
    使用.loc[]加index来进行行索引
    使用.iloc[]加整数来进行行索引
    同样返回一个Series,index为原来的columns。
    df.loc[[‘a‘,‘b‘]] # 取 a、b 两行
    df.iloc[[0, 1]] # 取 a、b 两行
    对元素索引
    df.loc[‘a‘, ‘3‘] # 取一个值,类似坐标取值
    df.loc[[‘a‘, ‘c‘], ‘3‘] # 取多个值
    df.loc[[‘a‘,‘c‘], [‘1‘, ‘2‘]]
  2. 切片
    【注意】 直接用中括号时
    索引表示的是列索引
    切片表示的是行切片

    切出前两行

    df[‘a‘:‘b‘]
    df[0:2]

    切出前两列

    df.loc[:, ‘A‘:‘B‘]
    df.iloc[:, 0:2]

    按照行列切片

    df.loc[‘a‘:‘b‘, ‘1‘:‘2‘]
  3. 运算
    和Series一样
    在运算中自动对齐不同索引的数据
    如果索引不对应,则补NaN
  4. 删除
    df.drop(1) # 默认删除行,即 axis=0
  5. 股票示例
    df.to_save(‘xxx.csv‘)
    pd.read_csv(‘xxx.csv‘, index_col=‘date‘, parse_dates=True):把字符串日期转为 Timestamp
    df.drop(labels=[‘列名‘], axis=1 ,inplace=True):删除某一列
    df[‘close‘].shift(1):向下移动一个单元,对齐其他列的下一行
    new_df.resample(‘M‘).first():获取每个月的第一条
    new_df.resample(‘A‘).last():获取每年的最后一条

    tushare 股票数据获取模块

    import tushare as ts
    import pands as pd

获取 股票代码 600519 从2001.1.1的交易数据

df = ts.get_k_data(code=‘600519‘,start=‘2000-01-01‘)

把数据保存到本地 maotai.csv 中

df.to_csv(‘./maotai.csv‘)

使用 pandas 读取文件

df = pd.read_csv(‘./maotai.csv‘)

删除某一列

df.drop(labels=[‘Unnamed: 0‘], axis=1, inplace=True)

把字符串的日期转换为 Timestamp 类型

df = pd.read_csv(‘./maotai.csv‘,index_col=‘date‘,parse_dates=[‘date‘])

查看转换结果

df.index[0]
df.columns[0]
输出该股票所有收盘比开盘上涨3%以上的日期。

(收盘-开盘)/开盘 > 0.03

df[(df.open - df.close)/df.open > 0.03]

将行索引取出

df.loc[(df[‘close‘] - df[‘open‘]) / df[‘open‘] > 0.03].index
输出该股票所有开盘比前日收盘跌幅超过2%的日期。

(开盘-前日收盘)/前日收盘 < -0.02

df[(df.open - df.close.shift(1)) / df.close.shift(1) < -0.02].index
假如我从2010年1月1日开始,每月第一个交易日买入1手股票,每年最后一个交易日卖出所有股票,到今天为止,我的收益如何?

2010-2019, M:表示按月份取,A:表示按年取

new_df = df[‘2010-01-01‘:‘2019-09-03‘]
df_monthly = new_df.resample(‘M‘).first()

除了最后一条数据

df_yearly = new_df.resample(‘A‘).last()[:-1]

计算买入股票花费

cost = df_monthly[‘open‘].sum() * 100
recv = df_yearly[‘open‘].sum() * 1200
recv = 900 * new_df[-1:][‘open‘] + recv
recv - cost
pandas的数据处理

  1. 处理丢失的数据
    numpy:没有异常值清洗

  2. None和np.nan(NaN)
    None:是python的object,nonetype,不能参与任何计算
    np.nan:是浮点类型,能参与计算中,计算结果还是NaN,不会影响整体的运算
    pandas中的None和NaN都强转为 np.nan
  3. 数据清洗
    如果出现NaN,可以把携带NaN的行删除或者替换NaN
  4. pandas处理空值(3)
    isnull()
    notnull()
    dropna():过滤丢失的数据
    fillna():填充丢失的数据

    空值检测

    df.isnull()
    df.notnull()

    True 和 False 的判定

    df.notnull().any(axis=1) # any表示or
    df.notnull().all(axis=1) # and

    去掉包含 NaN 的行,notnull + all, isnull + any

    将 df.notnull().all(axis=1)作为原数据的索引,就可以将对应的空进行删除

    df.loc[df.notnull().all(axis=1)] or
    indexs = df.loc[df.isnull().any(axis=1)].index
    df.drop[labels=indexs, axis=0]

    将 df.isnull().any(axis=1)作为原数据的索引,就可以将对应的空进行保留

    df.loc[df.isnull().any(axis=1)]
    df.dropna(axis=0):删除空行
    df.fillna(axis=0):用列的值进行替换

    直接删除空行

    df.dropna(axis=0)

    替换,ffill/bfill:forward/backward fill。用上(下)一行进行覆盖空值行数据

    df.fillna(value=‘目标值‘, method=‘ffill‘, axis=0)
    读取excel
    df = pd.read_excel(‘文件路径.xlsx‘, sheet_name=‘xxx‘)
    df = df.drop(labels=[‘none‘, ‘none1‘], axis=1 inplace=True)

    清洗,删除空对应的行数据,方式一

    df.dropna(axis=0)

    方式二

    df.loc[df.notnull().all(axis=1)]

清洗,替换空对应的行数据

df=df.fillna(method=‘ffill‘, axis=0).fillna(method=‘bfill‘, axis=0)

检测 df 列中是否还有空值

df.notnull().all(axis=0)
df.isnull().any(axis=0)

  1. pandas级联
  2. pd.concat()级联
    axis=0/1
    join=‘outer‘/‘inner‘
    不匹配指的是级联的维度的索引不一致。例如纵向级联时列索引不一致,横向级联时行索引不一致。有2种连接方式:
    外连接:补NaN(默认模式)
    内连接:只连接匹配的项
    df1 = DataFrame(np.random.randint(1,100, size=(5,5)))
    df2 = DataFrame(np.random.randint(1,100, size=(5,5)))

    匹配级联

    pd.concat((df1, df1), axis=0, join=‘outer‘)

    不匹配级联,索引不同会有空值

    pd.concat((df1, df2), axis=0, join=‘outer‘, sort=True)
  3. pd.merge()合并
    一次只能用于两张表,用于数据的整合
    参数说明
    left, right,
    how=‘inner/outer/left/right‘
    on=‘列名‘ , left_on=‘‘, right_on=‘‘
    merge与concat的区别在于,merge需要依据某一共同的列来进行合并,使用pd.merge()合并时,会自动根据两者相同column名称的那一列,作为key来进行合并。
    注意每一列元素的顺序不要求一致
    数据准备

    df1 数据一

    dic1 = {
    ‘name‘:[‘henry‘,‘echo‘, ‘dean‘, ‘tom‘],
    ‘apartment‘:[‘tech‘,‘sale‘,‘hr‘, ‘xx‘],
    }
    df1 = DataFrame(dic1, index=[‘a‘, ‘b‘, ‘c‘])

    df2 数据二

    dic2 = {
    ‘apartment‘:[‘tech‘,‘sale‘,‘hr‘, ‘acctounting‘],
    ‘supervisor‘:[‘diane‘, ‘oleg‘, ‘iris‘, ‘elaine‘]
    }
    df2 = DataFrame(dic2, index=[‘a‘, ‘b‘, ‘c‘])
    df2
  4. 一对一

    默认合并条件是相同的数据

    pd.merge(left=df1, right=df2, on=‘apartment‘)
  5. 一对多
    pd.merge(left=df1, right=df2, on=‘apartment‘, how=‘outer‘)
  6. 多对多
    pd.merge(left=df1, right=df2, on=‘apartment‘, how=‘inner‘)
    pd.merge(left=df1, right=df2, on=‘apartment‘, how=‘outer‘)
    pd.merge(left=df1, right=df2, on=‘apartment‘, how=‘left‘)
    pd.merge(left=df1, right=df2, on=‘apartment‘, how=‘right‘)
  7. key的规范化
    如果有两列名一样,on条件默认采用共同的合并条件
    合并条件的值不会重复出现,其他列名相同的值会重复出现(列名加后缀)
    当列冲突时,即有多个列名称相同时,需要使用on=来指定哪一个列作为key,配合suffixes指定冲突列名
    pd.merge(left=df1, right=df2, left_on=‘apartment‘,right_on=‘apart‘, how=‘right‘)
  8. 人口分析案例

    需求:

  9. 导入文件,查看原始数据
  10. 将人口数据和各州简称数据进行合并
  11. 将合并的数据中重复的abbreviation列进行删除
  12. 查看存在缺失数据的列
  13. 找到有哪些state/region使得state的值为NaN,进行去重操作
  14. 为找到的这些state/region的state项补上正确的值,从而去除掉state这一列的所有NaN
  15. 合并各州面积数据areas
  16. 我们会发现area(sq.mi)这一列有缺失数据,找出是哪些行,去除含有缺失数据的行
  17. 找出2010年的全民人口数据
    10.计算各州的人口密度 排序,并找出人口密度最高的五个州 df.sort_values()
    how=‘outer‘:要保留所有数据
    数据分析中要保证数据的完整性
    import pandas as pd
    import numpy as np
    from pandas import Series, DataFrame
    peo = pd.read_csv(‘./data/state-population.csv‘)
    area = pd.read_csv(‘./data/state-areas.csv‘)
    abbr = pd.read_csv(‘./data/state-abbrevs.csv‘)

将人口数据和各州简称数据进行合并

将合并的数据中重复的abbreviation列进行删除

abbr_peo = pd.merge(abbr, peo, left_on=‘abbreviation‘, right_on=‘state/region‘, how=‘outer‘)
abbr_peo.drop(labels=‘abbreviation‘, axis=1,inplace=True)
abbr_peo.head(2)

查看存在缺失数据的列

abbr_peo.isnull().any(axis=0)

找到有哪些state/region使得state的值为NaN,进行去重操作

abbr_peo.loc[abbr_peo.state[abbr_peo.state.isnull()].index][‘state/region‘].unique()

为找到的这些state/region的state项补上正确的值,从而去除掉state这一列的所有NaN

indexs = abbr_peo[abbr_peo[‘state/region‘] == ‘PR‘].index
abbr_peo.loc[indexs, ‘state‘] = ‘PUERTO RICO‘
indexs = abbr_peo[abbr_peo[‘state/region‘] == ‘USA‘].index
abbr_peo.loc[indexs, ‘state‘] = ‘UNITED STATES‘

合并各州面积数据areas

abbr_peo_area = pd.merge(abbr_peo, area, how=‘outer‘)
abbr_peo_area.head(2)

我们会发现area(sq.mi)这一列有缺失数据,找出是哪些行,去除含有缺失数据的行

indexs = abbr_peo_area[abbr_peo_area[‘area (sq. mi)‘].isnull()].index
abbr_peo_area.drop(labels=indexs, axis=0, inplace=True)

找出2010年的全民人口数据

abbr_peo_area.query("ages==‘total‘and year==2010")

计算各州的人口密度 排序,并找出人口密度最高的五个州 df.sort_values()

abbr_peo_area.peo_dense = abbr_peo_area.population / abbr_peo_area[‘area (sq. mi)‘]
abbr_peo_area.head(2)

排序,并找出人口密度最高的五个州 df.sort_values()

abbr_peo_area.sort_values(by=‘peo_dense‘,axis=0, ascending=False).head(2)

  1. pandas数据处理
  2. drop_duplicates:删重
    df.drop_duplicates(keep=‘first/last‘/False)
    keep参数:指定保留哪一重复的行数据
    df[0:2] = 6
    df.iloc[5] = 6

    keep表示保留重复行的方式

    df.drop_duplicates(keep=‘first/last‘/False)
  3. map():映射
  4. replace(to_replace=[]/{}, value=‘xxx‘):替换
    使用replace()函数,对values进行映射操作
    单值替换
    普通替换: 替换所有符合要求的元素:to_replace=15,value=‘e‘
    按列指定单值替换: to_replace={列标签:替换值} value=‘value‘
    多值替换
    列表替换: to_replace=[] value=[]
    字典替换(推荐) to_replace={to_replace:value,to_replace:value}

    指定单值替换,原数据为:64.0

    df.replace(to_replace={64:‘xxx‘})

    指定第三列的6替换

    df.replace(to_replace={2:6}, value=‘six‘)
  5. map():映射
    映射关系表:dict={}
    map()函数:新建一列,map函数并不是df的方法,而是series的方法
    map()可以映射新一列数据
    map()中可以使用lambd表达式
    map()中可以使用方法,可以是自定义的方法
    注意 :map()中不能使用sum之类的函数,for循环

dic = {
‘name‘:[‘周杰伦‘,‘张三‘,‘周杰伦‘],
‘salary‘:[15000,20000,15000]
}
df = DataFrame(data=dic)
df
name salary
0 周杰伦 15000
1 张三 20000
2 周杰伦 15000

映射关系表(字典)

dic = {
‘周杰伦‘:‘jay‘,
‘张三‘:‘tom‘
}
df[‘ename‘] = df.name.map(dic)

name    salary  ename

0 周杰伦 15000 jay
1 张三 20000 tom
2 周杰伦 15000 jay

map(),用法一

df.ename = df.name.map(dic)

用法二,在增加一列时,需要使用 [‘列名‘],如果直接使用 .列名 会失败

df[‘neat_salary‘] = df.salary.map(lambda x: x - (x-3000)*0.5)
df

  1. 使用聚合操作对异常值检测和过滤
    使用df.std()函数可以求得DataFrame对象的标准差
    创建一个1000行3列的df 范围(0-1),求其每一列的标准差

    生成测试的随机数据

    df = DataFrame(np.random.random(size=(1000, 3)), columns=[‘A‘, ‘B‘, ‘C‘])

    计算C列的标准差,并获取不合格的索引

    df.C.std()
    indexs = df[df.C > 3*df.C.std()].index
    indexs

    删除

    df.drop(labels=indexs, inplace=True, axis=0)
  2. 排序
    随机抽样:随机生成 0-n 的数组
    np.random.permutation(5)
    take():接收一个索引列表,用数字表示,使得df根据
    df.take(indices=np.random.permutation(1000)).take(indices=np.random.permutation(3), axis=1).head()
  3. 分组
    数据聚合是数据处理的最后一步,通常是要使每一个数组生成一个单一的数值。
    数据分类处理
    分组:先把数据分为几组
    用函数处理:为不同组的数据应用不同的函数以转换数据
    合并:把不同组得到的结果合并起来
    数据分类处理的核心
    groupby()函数
    groups属性查看分组情况
    eg: df.groupby(by=‘item‘).groups
    数据准备
    df = DataFrame({‘item‘:[‘Apple‘,‘Banana‘,‘Orange‘,‘Banana‘,‘Orange‘,‘Apple‘],
    ‘price‘:[4,3,3,2.5,4,2],
    ‘color‘:[‘red‘,‘yellow‘,‘yellow‘,‘green‘,‘green‘,‘green‘],
    ‘weight‘:[12,20,50,30,20,44]})
    df

    item price color weight
    0 Apple 4.0 red 12
    1 Banana 3.0 yellow 20
    2 Orange 3.0 yellow 50
    3 Banana 2.5 green 30
    4 Orange 4.0 green 20
    5 Apple 2.0 green 44
    groupby(‘分组条件‘)
    df.groupby(by=‘item‘, axis=0)
    df.groupby(by=‘item‘, axis=0).groups

    执行结果

    {‘Apple‘: Int64Index([0, 5], dtype=‘int64‘),
    ‘Banana‘: Int64Index([1, 3], dtype=‘int64‘),
    ‘Orange‘: Int64Index([2, 4], dtype=‘int64‘)}
    聚合
    mean_price = df.groupby(by=‘item‘, axis=0).price.mean()
    df[‘mean_price‘] = df.item.map(mean_price)
    df

color_price = df.groupby(by=‘color‘, axis=0).price.mean()
df[‘color_price‘] = df.color.map(color_price)
df

  1. 高级聚合
    transform和apply都会进行运算,在transform或者apply中传入函数即可
    transform和apply也可以传入一个lambda表达式
    def my_mean(p):
    sum = 0
    for i in p:
    sum += i
    return sum/len(p)

aplly_my_mean = df.groupby(by=‘item‘, axis=0).price.apply(my_mean)
df[‘apply_my_mean‘] = df.item.map(aplly_my_mean)
df

采用 transform 方法,transform是映射后的数据

transform_my_mean = df.groupby(by=‘item‘, axis=0).price.transform(my_mean)
df[‘transform_my_mean‘] = transform_my_mean
df

  1. 美国12政治选举案例
    需求

    字段说明

    cand_nm(候选人姓名),contbr_nm(捐赠者姓名), contbr_city,contbr_st, contbr_zip, contbr_employer, contbr_occupation(捐赠者的职业), contb_receipt_amt(捐赠金额), contb_receipt_dt(捐赠日期)

    具体需求

  2. 读取文件usa_election.txt
  3. 查看文件样式及基本信息
    3.【知识点】使用map函数+字典,新建一列各个候选人所在党派party
  4. 使用np.unique()函数查看colums:party这一列中有哪些元素
  5. 使用value_counts()函数,统计party列中各个元素出现次数,value_counts()是Series中的,无参,返回一个带有每个元素出现次数的Series
    6.【知识点】使用groupby()函数,查看各个党派收到的政治献金总数contb_receipt_amt
  6. 查看具体每天各个党派收到的政治献金总数contb_receipt_amt 。使用groupby([多个分组参数])
  7. 将表中日期格式转换为‘yyyy-mm-dd‘。日期格式,通过函数加map方式进行转换
  8. 得到每天各政党所收政治献金数目。 考察知识点:groupby(多个字段)
    10.查看老兵(捐献者职业)DISABLED VETERAN主要支持谁 :查看老兵们捐赠给谁的钱最多
    11.找出各个候选人的捐赠者中,捐赠金额最大的人的职业以及捐献额 .通过query("查询条件来查找捐献人职业")

    统计出现次数

    df[‘party‘].value_counts()

    多次分组,必须注意 by=[],中的分组顺序。类似文件的树形结构

    import numpy as np
    import pandas as pd
    import matplotlib.pyplot as plt

    1.读取文件usa_election.txt, 2.查看文件样式及基本信息

    usa_election = pd.read_csv(‘./data/usa_election.txt‘)
    usa_election.head(2)

    3.【知识点】使用map函数+字典,新建一列各个候选人所在党派party

    usa_election[‘parties‘] = usa_election[‘cand_nm‘].map(parties)
    usa_election.head(2)

    4.使用np.unique()函数查看colums:party这一列中有哪些元素

    usa_election.parties.unique()

    5.使用value_counts()函数,统计party列中各个元素出现次数,value_counts()是Series中的,无参,返回一个带有每个元素出现次数的Series

    usa_election.parties.value_counts()

    6.【知识点】使用groupby()函数,查看各个党派收到的政治献金总数contb_receipt_amt

    usa_election.groupby(by=‘parties‘).contb_receipt_amt.sum()

    7.查看具体每天各个党派收到的政治献金总数contb_receipt_amt 。使用groupby([多个分组参数])

    usa_election.groupby(by=[‘contb_receipt_dt‘, ‘parties‘])[‘contb_receipt_amt‘].sum()

    8.将表中日期格式转换为‘yyyy-mm-dd‘。日期格式,通过函数加map方式进行转换

    date = usa_election.contb_receipt_dt
    def transformDate(data):
    for i in range(len(date)):
    new_date = {}
    day, month, year = date[i].split(‘-‘)
    month = months[month]
    return ‘-‘.join([‘20‘+year, str(month), day])

usa_election[‘contb_receipt_dt‘] = usa_election.contb_receipt_dt.map(transformDate)
usa_election.head(2)

9.得到每天各政党所收政治献金数目。 考察知识点:groupby(多个字段)

usa_election.groupby(by=[‘contb_receipt_dt‘, ‘parties‘]).contb_receipt_amt.sum()

10.查看老兵(捐献者职业)DISABLED VETERAN主要支持谁 :查看老兵们捐赠给谁的钱最多

df = usa_election[usa_election.contbr_occupation ==‘DISABLED VETERAN‘]
df.groupby(by=‘cand_nm‘).contb_receipt_amt.sum()

11.找出各个候选人的捐赠者中,捐赠金额最大的人的职业以及捐献额 .通过query("查询条件来查找捐献人职业")

max_amt = usa_election.groupby(by=[‘cand_nm‘])[‘contb_receipt_amt‘].max()
max_amt

for i in range(max_amt.size):
max_money = max_amt[i]
# for 循环中不显示执行结果,需要使用display或者print
display(usa_election.query(‘contb_receipt_amt == ‘+str(max_money))

python数据分析三剑客

原文:https://www.cnblogs.com/yx12138/p/11585798.html

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!