文章目录
pandas高级操作
import pandas as pd
import numpy as np
from pandas import DataFrame
替换操作
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 |
---|
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 |
---|
映射操作
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一样充当运算工具
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')
<pandas.core.groupby.generic.DataFrameGroupBy object at 0x7fea8c556460>
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
数据加载
df = pd.read_csv('./data/type-.txt')
df
| 你好-我好-他也好 |
---|
0 | 也许-大概-有可能 |
---|
1 | 然而-未必-不见得 |
---|
df = pd.read_csv('./data/type-.txt',sep='-')
df
df = pd.read_csv('./data/type-.txt',sep='-',header=None)
df
| 0 | 1 | 2 |
---|
0 | 你好 | 我好 | 他也好 |
---|
1 | 也许 | 大概 | 有可能 |
---|
2 | 然而 | 未必 | 不见得 |
---|
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 | 然而 | 未必 | 不见得 |
---|
df = pd.read_csv('./data/test.txt',sep='\s+',header=None,names=['A','B','C'])
df
| A | B | C |
---|
0 | 你好 | 我好 | 他也好 |
---|
1 | 也许 | 大概 | 有可能 |
---|
2 | 然而 | 未必 | 不见得 |
---|
透视表
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 |
---|
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 |
---|
df.pivot_table(index='主客场',values='得分',aggfunc='sum')
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')
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 |
---|