python数据分析基础02——pandas相关操作

文章目录

      • pandas高级操作
        • 替换操作
        • 映射操作
        • 运算工具
        • 排序实现的随机抽样
        • 数据的分类处理
        • 高级数据聚合
        • 数据加载
        • 透视表
        • 交叉表

pandas高级操作

import pandas as pd
import numpy as np
from pandas import DataFrame

替换操作

  • 替换操作可以同步作用于Series和DataFrame中

  • 单值替换

    • 普通替换: 替换所有符合要求的元素:to_replace=15,value=‘e’
    • 按列指定单值替换: to_replace={列标签:替换值} value=‘value’
  • 多值替换

    • 列表替换: to_replace=[] value=[]
    • 字典替换(推荐) to_replace={to_replace:value,to_replace:value}
df = DataFrame(data=np.random.randint(0,20,size=(8,5)))
df
0 1 2 3 4
0 17 0 17 11 6
1 8 3 7 7 3
2 9 13 4 19 3
3 12 3 0 10 16
4 8 5 5 4 14
5 14 18 2 1 3
6 14 6 8 15 5
7 2 7 7 18 11
#全局替换
df.replace(to_replace=1,value='one')
0 1 2 3 4
0 17 0 17 11 6
1 8 3 7 7 3
2 9 13 4 19 3
3 12 3 0 10 16
4 8 5 5 4 14
5 14 18 2 one 3
6 14 6 8 15 5
7 2 7 7 18 11
#多值替换:将多个值替换成指定形式
df.replace(to_replace={1:'one',3:'three'})
0 1 2 3 4
0 17 0 17 11 6
1 8 three 7 7 three
2 9 13 4 19 three
3 12 three 0 10 16
4 8 5 5 4 14
5 14 18 2 one three
6 14 6 8 15 5
7 2 7 7 18 11
#指定列的替换:字典的key表示指定的列索引,字典的value值就是要替换的元素
df.replace(to_replace={3:17},value='one')
0 1 2 3 4
0 13 10 14 2 17
1 17 2 4 one 9
2 2 3 10 one 13
3 17 15 19 13 15
4 10 5 17 7 4
5 3 2 0 0 13
6 6 8 0 16 1
7 15 13 10 6 18

映射操作

  • 概念:创建一个映射关系列表,把values元素和一个特定的标签或者字符串绑定(给一个元素值提供不同的表现形式)

  • 创建一个df,两列分别是姓名和薪资,然后给其名字起对应的英文名

dic = {
    'name':['张三','李四','王五','张三'],
    'salary':[5000,6000,5500,5000]
}
df = DataFrame(data=dic)
df
name salary
0 张三 5000
1 李四 6000
2 王五 5500
3 张三 5000
#映射关系表
dic = {
    '李四':'Jerry',
    '王五':'Jack',
    '张三':'Tom'
}
e_name = df['name'].map(dic)
df['e_name'] = e_name
df
name salary e_name
0 张三 5000 Tom
1 李四 6000 Jerry
2 王五 5500 Jack
3 张三 5000 Tom
  • map是Series的方法,只能被Series调用

运算工具

  • 超过3000部分的钱缴纳50%的税,计算每个人的税后薪资
def after_sal(s):
    return s - (s-3000)*0.5
after_salary = df['salary'].map(after_sal)
df['after_salary'] = after_salary
df
name salary e_name after_salary
0 张三 5000 Tom 4000.0
1 李四 6000 Jerry 4500.0
2 王五 5500 Jack 4250.0
3 张三 5000 Tom 4000.0
  • Series的方法apply也可以像map一样充当运算工具
    • apply充当运算工具效率要远远高于map
def after_sal(s):
    return s - (s-3000)*0.5
after_salary = df['salary'].apply(after_sal)
after_salary
0    4000.0
1    4500.0
2    4250.0
3    4000.0
Name: salary, dtype: float64

排序实现的随机抽样

  • take()
  • np.random.permutation(n):返回0-(n-1)之间的随机序列
df = DataFrame(data=np.random.random(size=(100,3)),columns=['A','B','C'])
df.head()
A B C
0 0.443835 0.973331 0.626923
1 0.366619 0.225035 0.719683
2 0.431639 0.154259 0.051419
3 0.406994 0.065048 0.145229
4 0.965849 0.385788 0.208316
#将行打乱
df.take(np.random.permutation(100),axis=0)
A B C
88 0.882121 0.368332 0.158629
96 0.319008 0.251546 0.009901
28 0.696431 0.178469 0.125718
23 0.268010 0.639662 0.137387
22 0.599899 0.089535 0.930574
... ... ... ...
50 0.468952 0.562839 0.671872
79 0.237526 0.228043 0.699325
87 0.932147 0.394211 0.540368
90 0.980401 0.823402 0.624730
92 0.699101 0.108088 0.542962

100 rows × 3 columns

#将行列打乱
df.take(np.random.permutation(100),axis=0).take(indices=np.random.permutation(3),axis=1)
B A C
46 0.274198 0.689843 0.119163
6 0.493573 0.854749 0.134710
55 0.572823 0.159019 0.124300
65 0.982499 0.822922 0.788931
5 0.578393 0.904401 0.866710
... ... ... ...
30 0.734058 0.948066 0.029316
59 0.103037 0.748319 0.025966
48 0.988017 0.194801 0.162126
80 0.594385 0.471618 0.945606
70 0.750110 0.592528 0.470297

100 rows × 3 columns

#将行列打乱,然后进行随机抽样
df.take(np.random.permutation(100),axis=0).take(indices=np.random.permutation(3),axis=1)[0:5]
A B C
38 0.605719 0.843236 0.339796
32 0.779512 0.944551 0.109526
70 0.243308 0.799665 0.374344
37 0.929103 0.907324 0.259208
21 0.963018 0.868906 0.874337

数据的分类处理

  • 数据分类处理的核心:

    • groupby()函数
    • 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
df.groupby(by='item')#返回了DataFrameGroupBy对象,分组的结果都存储在了该对象中

#groups查看分组详情
df.groupby(by='item').groups
{'Apple': [0, 5], 'Banana': [1, 3], 'Orange': [2, 4]}
#计算每种水果的平均价格
df.groupby(by='item').mean()
df.groupby(by='item').mean()['price'] #不推荐:浪费了算力
item
Apple     3.00
Banana    2.75
Orange    3.50
Name: price, dtype: float64
df.groupby(by='item')['price'].mean()#推荐方式
item
Apple     3.00
Banana    2.75
Orange    3.50
Name: price, dtype: float64
#多个分组条件
df.groupby(by=['item','color'])
df.groupby(by=['color','item']).sum()
price weight
color item
green Apple 2.0 44
Banana 2.5 30
Orange 4.0 20
red Apple 4.0 12
yellow Banana 3.0 20
Orange 3.0 50
#需求:计算出每种水果的平均价格,然后将平均价格汇总到原始的表格中
mean_price_s = df.groupby(by='item')['price'].mean()
mean_price_s
item
Apple     3.00
Banana    2.75
Orange    3.50
Name: price, dtype: float64
dic = mean_price_s.to_dict() #映射关系表
df['mean_price'] = df['item'].map(dic)
df
item price color weight mean_price
0 Apple 4.0 red 12 3.00
1 Banana 3.0 yellow 20 2.75
2 Orange 3.0 yellow 50 3.50
3 Banana 2.5 green 30 2.75
4 Orange 4.0 green 20 3.50
5 Apple 2.0 green 44 3.00
#每种颜色水果的平均重量
mean_weight_s = df.groupby(by='color')['weight'].mean()
dic = mean_weight_s.to_dict()
mean_weight = df['color'].map(dic)
df['mean_weight'] = mean_weight
df
item price color weight mean_price mean_weight
0 Apple 4.0 red 12 3.00 12.000000
1 Banana 3.0 yellow 20 2.75 35.000000
2 Orange 3.0 yellow 50 3.50 35.000000
3 Banana 2.5 green 30 2.75 31.333333
4 Orange 4.0 green 20 3.50 31.333333
5 Apple 2.0 green 44 3.00 31.333333

高级数据聚合

  • 使用groupby分组后,也可以使用transform和apply提供自定义函数实现更多的运算
  • df.groupby(‘item’)[‘price’].sum() <==> df.groupby(‘item’)[‘price’].apply(sum)
  • transform和apply都会进行运算,在transform或者apply中传入函数即可
  • transform和apply也可以传入一个lambda表达式
def my_mean(p):
    sum = 0
    for i in p:
        sum += i
    return sum / len(p)
# 每种水果的平均价格值,不需要做映射就可汇总到原始表
df.groupby(by='item')['price'].transform(my_mean)
0    3.00
1    2.75
2    3.50
3    2.75
4    3.50
5    3.00
Name: price, dtype: float64
# 每种水果的平均价格值,需要做映射才能汇总到原始表
df.groupby(by='item')['price'].apply(my_mean)
item
Apple     3.00
Banana    2.75
Orange    3.50
Name: price, dtype: float64

数据加载

  • 读取type-.txt文件数据
df = pd.read_csv('./data/type-.txt')
df
你好-我好-他也好
0 也许-大概-有可能
1 然而-未必-不见得
df = pd.read_csv('./data/type-.txt',sep='-')
df
你好 我好 他也好
0 也许 大概 有可能
1 然而 未必 不见得
df = pd.read_csv('./data/type-.txt',sep='-',header=None)
df
0 1 2
0 你好 我好 他也好
1 也许 大概 有可能
2 然而 未必 不见得
#\s+表示一个或者多个空格
df = pd.read_csv('./data/test.txt',sep='\s+',header=None)
df
0 1 2
0 你好 我好 他也好
1 也许 大概 有可能
2 然而 未必 不见得
#修改列索引
df.columns = ['a','b','c']
df
a b c
0 你好 我好 他也好
1 也许 大概 有可能
2 然而 未必 不见得
df.rename(index={0:'a1',1:'a2',2:'a3'})
a b c
a1 你好 我好 他也好
a2 也许 大概 有可能
a3 然而 未必 不见得
#参数names可以在读取数据的时候直接修改列索引
df = pd.read_csv('./data/test.txt',sep='\s+',header=None,names=['A','B','C'])
df
A B C
0 你好 我好 他也好
1 也许 大概 有可能
2 然而 未必 不见得

透视表

  • 透视表是一种可以对数据动态排布并且分类汇总的表格格式。或许大多数人都在Excel使用过数据透视表,也体会到它的强大功能,而在pandas中它被称作pivot_table。

  • 透视表的优点:

    • 灵活性高,可以随意定制你的分析计算要求
    • 脉络清晰易于理解数据
    • 操作性强,报表神器
df = pd.read_csv('./data/透视表-篮球赛.csv')
df.head()
对手 胜负 主客场 命中 投篮数 投篮命中率 3分命中率 篮板 助攻 得分
0 勇士 10 23 0.435 0.444 6 11 27
1 国王 8 21 0.381 0.286 3 9 27
2 小牛 10 19 0.526 0.462 3 7 29
3 灰熊 8 20 0.400 0.250 5 8 22
4 76人 10 20 0.500 0.250 3 13 27

pivot_table有四个最重要的参数index、values、columns、aggfunc

  • index参数:分类汇总的分类条件
    • 每个pivot_table必须拥有一个index。如果想查看哈登对阵每个队伍的得分则需要对每一个队进行分类并计算其各类得分的平均值:
df.pivot_table(index='胜负')
3分命中率 助攻 命中 得分 投篮命中率 投篮数 篮板
胜负
0.42819 9.666667 10.238095 32.952381 0.481524 21.142857 5.142857
0.29350 8.500000 7.500000 27.250000 0.354250 21.250000 4.750000
  • 想看看哈登对阵同一对手在不同主客场下的数据,分类条件为对手和主客场
df.pivot_table(index=['对手','主客场'])
3分命中率 助攻 命中 得分 投篮命中率 投篮数 篮板
对手 主客场
76人 0.4290 7.0 8.0 29.0 0.381 21.0 4.0
0.2500 13.0 10.0 27.0 0.500 20.0 3.0
勇士 0.4440 11.0 10.0 27.0 0.435 23.0 6.0
国王 0.2860 9.0 8.0 27.0 0.381 21.0 3.0
太阳 0.5450 7.0 12.0 48.0 0.545 22.0 2.0
小牛 0.4620 7.0 10.0 29.0 0.526 19.0 3.0
尼克斯 0.3850 10.0 12.0 37.0 0.444 27.0 2.0
0.3530 9.0 9.0 31.0 0.391 23.0 5.0
开拓者 0.5710 3.0 16.0 48.0 0.552 29.0 8.0
掘金 0.1430 9.0 6.0 21.0 0.375 16.0 8.0
步行者 0.3330 10.0 8.0 29.0 0.364 22.0 8.0
0.2500 15.0 9.0 26.0 0.429 21.0 5.0
湖人 0.4440 9.0 13.0 36.0 0.591 22.0 4.0
灰熊 0.3395 8.0 9.5 30.0 0.420 22.5 4.5
0.3610 7.5 7.5 24.5 0.383 19.5 4.5
爵士 0.8750 13.0 19.0 56.0 0.760 25.0 2.0
0.3330 3.0 8.0 29.0 0.421 19.0 5.0
猛龙 0.2730 11.0 8.0 38.0 0.320 25.0 6.0
篮网 0.6150 8.0 13.0 37.0 0.650 20.0 10.0
老鹰 0.5450 11.0 8.0 29.0 0.533 15.0 3.0
骑士 0.4290 13.0 8.0 35.0 0.381 21.0 11.0
鹈鹕 0.4000 17.0 8.0 26.0 0.500 16.0 1.0
黄蜂 0.4000 11.0 8.0 27.0 0.444 18.0 10.0
  • values参数:需要对计算的数据进行筛选
    • 如果我们只需要哈登在主客场和不同胜负情况下的得分、篮板与助攻三项数据:
df.pivot_table(index=['主客场','胜负'],values=['得分','篮板','助攻'])
助攻 得分 篮板
主客场 胜负
10.555556 34.222222 5.444444
8.666667 29.666667 5.000000
9.000000 32.000000 4.916667
8.000000 20.000000 4.000000
  • Aggfunc参数:设置我们对数据聚合时进行的函数操作

    • 当我们未设置aggfunc时,它默认aggfunc='mean’计算均值。
  • 还想获得james harden在主客场和不同胜负情况下的总得分、总篮板、总助攻时:

df.pivot_table(index=['主客场','胜负'],values=['得分','篮板','助攻'],aggfunc='sum')
助攻 得分 篮板
主客场 胜负
95 308 49
26 89 15
108 384 59
8 20 4
df.pivot_table(index=['主客场','胜负'],aggfunc={'得分':'sum','篮板':'mean','助攻':'min'})
助攻 得分 篮板
主客场 胜负
7 308 5.444444
7 89 5.000000
3 384 4.916667
8 20 4.000000
  • Columns:可以设置列层次字段
    • 对values字段进行分类
#获取所有队主客场的总得分
df.pivot_table(index='主客场',values='得分',aggfunc='sum')
得分
主客场
397
404
#查看主客场下的总得分的组成元素是谁
df.pivot_table(index='主客场',values='得分',aggfunc='sum',columns='对手',fill_value=0)
对手 76人 勇士 国王 太阳 小牛 尼克斯 开拓者 掘金 步行者 湖人 灰熊 爵士 猛龙 篮网 老鹰 骑士 鹈鹕 黄蜂
主客场
29 0 0 0 29 37 0 21 29 0 60 56 38 37 0 35 26 0
27 27 27 48 0 31 48 0 26 36 49 29 0 0 29 0 0 27

交叉表

  • 是一种用于计算分组的特殊透视图,对数据进行汇总
  • pd.crosstab(index,colums)
    • index:分组数据,交叉表的行索引
    • columns:交叉表的列索引
import pandas as pd
from pandas import DataFrame
df = DataFrame({'sex':['man','man','women','women','man','women','man','women','women'],
               'age':[15,23,25,17,35,57,24,31,22],
               'smoke':[True,False,False,True,True,False,False,True,False],
               'height':[168,179,181,166,173,178,188,190,160]})
df
sex age smoke height
0 man 15 True 168
1 man 23 False 179
2 women 25 False 181
3 women 17 True 166
4 man 35 True 173
5 women 57 False 178
6 man 24 False 188
7 women 31 True 190
8 women 22 False 160
  • 求出各个性别抽烟的人数
#分组
df.groupby(by='sex')['smoke'].sum()
#透视
df.pivot_table(index='sex',values='smoke',aggfunc='sum')
smoke
sex
man 2
women 2
pd.crosstab(df.smoke,df.sex)
sex man women
smoke
False 2 3
True 2 2
pd.crosstab(df.sex,df.smoke)
smoke False True
sex
man 2 2
women 3 2
  • 求出各个年龄段抽烟人情况
pd.crosstab(df.smoke,df.age)
age 15 17 22 23 24 25 31 35 57
smoke
False 0 0 1 1 1 1 0 0 1
True 1 1 0 0 0 0 1 1 0

你可能感兴趣的:(大数据——数据挖掘,python,数据分析,数据挖掘)