上一篇:pandas数据分析给力教程【完整版】(五)
下一篇:pandas数据分析给力教程【完整版】(七)
import pandas as pd
from pandas import Series,DataFrame
import numpy as np
pandas数据处理
1、删除重复元素
def make_df(index, cols):
df = DataFrame({col: [col + str(i) for i in index] for col in cols})
df.index = index
return df
df = make_df([1,2,3,4], list('ABCD'))
df
A | B | C | D | |
---|---|---|---|---|
1 | A1 | B1 | C1 | D1 |
2 | A2 | B2 | C2 | D2 |
3 | A3 | B3 | C3 | D3 |
4 | A4 | B4 | C4 | D4 |
使用duplicated()函数检测重复的行,返回元素为布尔类型的Series对象,每个元素对应一行,如果该行不是第一次出现,则元素为True
df.duplicated()
1 False
2 False
3 False
4 False
dtype: bool
df.loc[2] = df.loc[1]
df
A | B | C | D | |
---|---|---|---|---|
1 | A1 | B1 | C1 | D1 |
2 | A1 | B1 | C1 | D1 |
3 | A3 | B3 | C3 | D3 |
4 | A4 | B4 | C4 | D4 |
df.duplicated(keep='last')
1 True
2 False
3 False
4 False
dtype: bool
df.loc[1, 'D'] = 'D4'
df
A | B | C | D | |
---|---|---|---|---|
1 | A1 | B1 | C1 | D4 |
2 | A1 | B1 | C1 | D1 |
3 | A3 | B3 | C3 | D3 |
4 | A4 | B4 | C4 | D4 |
df.duplicated(subset=['A', 'B', 'C'])
1 False
2 True
3 False
4 False
dtype: bool
使用drop_duplicates()函数删除重复的行
df.drop_duplicates()
A | B | C | D | |
---|---|---|---|---|
1 | A1 | B1 | C1 | D1 |
3 | A3 | B3 | C3 | D3 |
4 | A4 | B4 | C4 | D4 |
df[~df.duplicated()]
A | B | C | D | |
---|---|---|---|---|
1 | A1 | B1 | C1 | D1 |
3 | A3 | B3 | C3 | D3 |
4 | A4 | B4 | C4 | D4 |
df[np.logical_not(df.duplicated())]
A | B | C | D | |
---|---|---|---|---|
1 | A1 | B1 | C1 | D1 |
3 | A3 | B3 | C3 | D3 |
4 | A4 | B4 | C4 | D4 |
2. 映射
映射的含义:创建一个映射关系列表,把values元素和一个特定的标签或者字符串绑定
需要使用字典:
map = { 'label1':'value1', 'label2':'value2', ... }
包含三种操作:
- replace()函数:替换元素
- 最重要:map()函数:新建一列
- rename()函数:替换索引
1) replace()函数:替换元素
使用replace()函数,对values进行替换操作
data = np.random.randint(0,150, size=(4,3))
index = ['张三', '李四', '王五', '赵六']
columns = ['语文', '数学', '英语']
df = DataFrame(index=index, data=data, columns=columns)
df
语文 | 数学 | 英语 | |
---|---|---|---|
张三 | 119 | 103 | 18 |
李四 | 5 | 103 | 89 |
王五 | 79 | 11 | 32 |
赵六 | 93 | 14 | 32 |
首先定义一个字典
mapping = {34: 104, 37: 107, 17: 117, 43: 134}
调用.replace()
df.replace(mapping)
语文 | 数学 | 英语 | |
---|---|---|---|
张三 | 93 | 134 | 86 |
李四 | 104 | 54 | 97 |
王五 | 111 | 107 | 60 |
赵六 | 125 | 117 | 38 |
replace还经常用来替换NaN元素
df.iloc[0,0] = np.nan
df
语文 | 数学 | 英语 | |
---|---|---|---|
张三 | NaN | 43 | 86 |
李四 | 34.0 | 54 | 97 |
王五 | 111.0 | 37 | 60 |
赵六 | 125.0 | 17 | 38 |
df.replace({np.nan: 0})
语文 | 数学 | 英语 | |
---|---|---|---|
张三 | 0.0 | 43 | 86 |
李四 | 34.0 | 54 | 97 |
王五 | 111.0 | 37 | 60 |
赵六 | 125.0 | 17 | 38 |
============================================
练习19:
假设张三李四的课表里有满分的情况,老师认为是作弊,把所有满分的情况(包括150,300分)都记0分,如何实现?
============================================
df.iloc[0,0] = 150
df.iloc[1,0] = 150
df
语文 | 数学 | 英语 | |
---|---|---|---|
张三 | 150.0 | 43 | 86 |
李四 | 150.0 | 54 | 97 |
王五 | 111.0 | 37 | 60 |
赵六 | 125.0 | 17 | 38 |
df.replace({150: 0})
语文 | 数学 | 英语 | |
---|---|---|---|
张三 | 0.0 | 43 | 86 |
李四 | 0.0 | 54 | 97 |
王五 | 111.0 | 37 | 60 |
赵六 | 125.0 | 17 | 38 |
2) map()函数:新建一列
使用map()函数,由已有的列生成一个新列
适合处理某一单独的列。
df
语文 | 数学 | 英语 | |
---|---|---|---|
张三 | 150.0 | 43 | 86 |
李四 | 150.0 | 54 | 97 |
王五 | 111.0 | 37 | 60 |
赵六 | 125.0 | 17 | 38 |
# map的基本用法: 根据已有列的数据来生成新的一列数据
df['理综'] = df['数学'].map({43: 243, 54: 254, 37: 237, 17: 217})
df
语文 | 数学 | 英语 | 理综 | |
---|---|---|---|---|
张三 | 150.0 | 43 | 86 | 243 |
李四 | 150.0 | 54 | 97 | 254 |
王五 | 111.0 | 37 | 60 | 237 |
赵六 | 125.0 | 17 | 38 | 217 |
# 用法二: 修改已有列的数据
df['数学'] = df['数学'].map({43:143, 54: 124, 37: 137, 17: 117})
df
语文 | 数学 | 英语 | 理综 | |
---|---|---|---|---|
张三 | 150.0 | 143 | 86 | 243 |
李四 | 150.0 | 124 | 97 | 254 |
王五 | 111.0 | 137 | 60 | 237 |
赵六 | 125.0 | 117 | 38 | 217 |
仍然是新建一个字典
map()函数中可以使用lambda函数
# 用法三: 传递lambda函数
df['及格与否'] = df['英语'].map(lambda item: item >= 60)
df
语文 | 数学 | 英语 | 理综 | 及格与否 | |
---|---|---|---|---|---|
张三 | 150.0 | 143 | 86 | 243 | True |
李四 | 150.0 | 124 | 97 | 254 | True |
王五 | 111.0 | 137 | 60 | 237 | True |
赵六 | 125.0 | 117 | 38 | 217 | False |
df['python'] = df['英语'].map(lambda item: item * 2)
df
语文 | 数学 | 英语 | 理综 | 及格与否 | python | |
---|---|---|---|---|---|---|
张三 | 150.0 | 143 | 86 | 243 | True | 172 |
李四 | 150.0 | 124 | 97 | 254 | True | 194 |
王五 | 111.0 | 137 | 60 | 237 | True | 120 |
赵六 | 125.0 | 117 | 38 | 217 | False | 76 |
def convert(item):
if item >= 80:
return '优秀'
elif item >= 60:
return '及格'
else:
return '不及格'
# map第四个用法: 传递一个普通函数
df['score'] = df['英语'].map(convert)
df
语文 | 数学 | 英语 | 理综 | 及格与否 | python | score | |
---|---|---|---|---|---|---|---|
张三 | 150.0 | 143 | 86 | 243 | True | 172 | 优秀 |
李四 | 150.0 | 124 | 97 | 254 | True | 194 | 优秀 |
王五 | 111.0 | 137 | 60 | 237 | True | 120 | 及格 |
赵六 | 125.0 | 117 | 38 | 217 | False | 76 | 不及格 |
transform()和map()类似
df['score1'] = df['英语'].transform(convert)
df
语文 | 数学 | 英语 | 理综 | 及格与否 | python | score | score1 | |
---|---|---|---|---|---|---|---|---|
张三 | 150.0 | 143 | 86 | 243 | True | 172 | 优秀 | 优秀 |
李四 | 150.0 | 124 | 97 | 254 | True | 194 | 优秀 | 优秀 |
王五 | 111.0 | 137 | 60 | 237 | True | 120 | 及格 | 及格 |
赵六 | 125.0 | 117 | 38 | 217 | False | 76 | 不及格 | 不及格 |
使用map()函数新建一个新列
============================================
练习20:
新增两列,分别为张三、李四的成绩状态,如果分数低于90,则为"failed",如果分数高于120,则为"excellent",其他则为"pass"
【提示】使用函数作为map的参数
============================================
3) rename()函数:替换索引
仍然是新建一个字典
df
语文 | 数学 | 英语 | 理综 | 及格与否 | python | score | score1 | |
---|---|---|---|---|---|---|---|---|
张三 | 150.0 | 143 | 86 | 243 | True | 172 | 优秀 | 优秀 |
李四 | 150.0 | 124 | 97 | 254 | True | 194 | 优秀 | 优秀 |
王五 | 111.0 | 137 | 60 | 237 | True | 120 | 及格 | 及格 |
赵六 | 125.0 | 117 | 38 | 217 | False | 76 | 不及格 | 不及格 |
mapping = {'语文': 'Chinese', '数学': 'Math', '英语': 'English'}
df.rename(mapping, axis=1)
Chinese | Math | English | 理综 | 及格与否 | python | score | score1 | |
---|---|---|---|---|---|---|---|---|
张三 | 150.0 | 143 | 86 | 243 | True | 172 | 优秀 | 优秀 |
李四 | 150.0 | 124 | 97 | 254 | True | 194 | 优秀 | 优秀 |
王五 | 111.0 | 137 | 60 | 237 | True | 120 | 及格 | 及格 |
赵六 | 125.0 | 117 | 38 | 217 | False | 76 | 不及格 | 不及格 |
df.rename(columns=mapping)
Chinese | Math | English | 理综 | 及格与否 | python | score | score1 | |
---|---|---|---|---|---|---|---|---|
张三 | 150.0 | 143 | 86 | 243 | True | 172 | 优秀 | 优秀 |
李四 | 150.0 | 124 | 97 | 254 | True | 194 | 优秀 | 优秀 |
王五 | 111.0 | 137 | 60 | 237 | True | 120 | 及格 | 及格 |
赵六 | 125.0 | 117 | 38 | 217 | False | 76 | 不及格 | 不及格 |
df.rename(index={'张三': 'Mr Zhang', '李四': 'Mr Lee', '王五': 'Lao Wang', '赵六': 'Mr Six'})
语文 | 数学 | 英语 | 理综 | 及格与否 | python | score | score1 | |
---|---|---|---|---|---|---|---|---|
Mr Zhang | 150.0 | 143 | 86 | 243 | True | 172 | 优秀 | 优秀 |
Mr Lee | 150.0 | 124 | 97 | 254 | True | 194 | 优秀 | 优秀 |
Lao Wang | 111.0 | 137 | 60 | 237 | True | 120 | 及格 | 及格 |
Mr Six | 125.0 | 117 | 38 | 217 | False | 76 | 不及格 | 不及格 |
使用rename()函数替换行索引
3. 异常值检测和过滤
使用describe()函数查看每一列的描述性统计量
df.describe()
语文 | 数学 | 英语 | 理综 | python | |
---|---|---|---|---|---|
count | 4.00000 | 4.000000 | 4.000000 | 4.00000 | 4.000000 |
mean | 134.00000 | 130.250000 | 70.250000 | 237.75000 | 140.500000 |
std | 19.33908 | 11.870833 | 26.512576 | 15.52149 | 53.025151 |
min | 111.00000 | 117.000000 | 38.000000 | 217.00000 | 76.000000 |
25% | 121.50000 | 122.250000 | 54.500000 | 232.00000 | 109.000000 |
50% | 137.50000 | 130.500000 | 73.000000 | 240.00000 | 146.000000 |
75% | 150.00000 | 138.500000 | 88.750000 | 245.75000 | 177.500000 |
max | 150.00000 | 143.000000 | 97.000000 | 254.00000 | 194.000000 |
使用std()函数可以求得DataFrame对象每一列的标准差
根据每一列的标准差,对DataFrame元素进行过滤。
借助any()函数, 测试是否有True,有一个或以上返回True,反之返回False
对每一列应用筛选条件,去除标准差太大的数据
删除特定索引df.drop(labels,inplace = True)
============================================
练习21:
新建一个形状为10000*3的标准正态分布的DataFrame(np.random.randn),去除掉所有满足以下情况的行:其中任一元素绝对值大于3倍标准差
============================================
异常值的检测一定要有一个标准.具体的标准要根据具体业务来分析.
df = DataFrame(data=np.random.randn(10000,3))
df.head()
0 | 1 | 2 | |
---|---|---|---|
0 | 0.702958 | 1.076957 | 0.300606 |
1 | 0.078124 | 0.071552 | 0.182246 |
2 | 1.121916 | -1.379986 | 0.489360 |
3 | 0.633601 | -0.864642 | 0.015258 |
4 | -1.379120 | -0.583192 | -0.290505 |
df.std()
0 1.002128
1 0.991692
2 1.002605
dtype: float64
df[~(df.abs() > 3 * df.std()).any(axis=1)]
0 | 1 | 2 | |
---|---|---|---|
0 | 0.702958 | 1.076957 | 0.300606 |
1 | 0.078124 | 0.071552 | 0.182246 |
2 | 1.121916 | -1.379986 | 0.489360 |
3 | 0.633601 | -0.864642 | 0.015258 |
4 | -1.379120 | -0.583192 | -0.290505 |
5 | 0.618883 | -1.104339 | -0.570237 |
6 | 0.916081 | -0.108372 | 0.460898 |
7 | 0.214117 | 0.860870 | -0.205388 |
8 | -0.253403 | 0.142603 | 1.670119 |
9 | -0.905850 | -0.196322 | 2.690032 |
10 | 0.384971 | -0.080958 | 0.679500 |
11 | -0.807132 | 0.588866 | 0.415264 |
12 | -0.763031 | -1.796780 | 0.573219 |
13 | -0.274970 | -1.288599 | 1.230828 |
14 | -0.571952 | 0.724518 | -1.341576 |
15 | -1.159281 | -1.443461 | 1.321074 |
16 | 1.632015 | 0.523967 | -0.416220 |
17 | -0.951032 | -1.109964 | -1.268240 |
18 | -0.258133 | 0.240632 | -0.534827 |
19 | 0.459025 | 0.666112 | 0.292500 |
20 | -0.349553 | 0.329076 | -1.036976 |
21 | 0.704763 | 0.487110 | -0.474845 |
22 | -0.862090 | 0.241097 | -0.348680 |
23 | 0.926968 | -0.824318 | 0.215676 |
24 | -0.974620 | 0.478644 | -0.227909 |
25 | 0.271325 | 1.496910 | 0.335745 |
26 | 0.609025 | 0.187004 | 0.656713 |
28 | -2.312873 | 0.049148 | 0.195795 |
29 | 1.114768 | 1.229843 | 0.165681 |
30 | 1.498970 | 0.590742 | 0.324432 |
... | ... | ... | ... |
9969 | 0.671424 | -0.416264 | 0.068488 |
9970 | 1.167870 | -0.409707 | 1.541785 |
9971 | 2.202169 | -0.427342 | 1.890037 |
9972 | 0.977254 | -0.203149 | -0.179609 |
9973 | 0.344181 | 0.905022 | -0.519217 |
9974 | 1.440256 | 0.690965 | -0.847224 |
9975 | -1.423468 | 1.255630 | 0.067692 |
9976 | 2.131677 | 1.729157 | 0.073778 |
9977 | -0.859171 | 0.497846 | -0.212514 |
9979 | -2.410043 | 0.271282 | 0.518025 |
9980 | -0.085760 | 0.583119 | 0.586410 |
9981 | 1.713973 | -0.068664 | 1.032057 |
9982 | -1.700565 | -0.126339 | -0.129507 |
9983 | -0.129577 | -0.513998 | 0.437219 |
9984 | 2.381347 | -1.657040 | -0.227971 |
9985 | -0.775950 | -1.122079 | -1.177830 |
9986 | 0.706769 | 0.022441 | 1.624407 |
9987 | -1.490968 | -0.959855 | 0.185482 |
9988 | -0.450941 | 1.017665 | 1.622394 |
9989 | 0.380156 | 0.512397 | 1.219214 |
9990 | 1.132431 | -0.374839 | -0.475572 |
9991 | 0.271683 | 1.430147 | -0.285015 |
9992 | -1.276515 | -0.682312 | 0.557811 |
9993 | 0.084578 | 0.518161 | -0.441114 |
9994 | 0.569201 | 0.674269 | 0.249646 |
9995 | 1.249458 | 0.809205 | -0.215635 |
9996 | 1.021031 | -0.480514 | -0.971789 |
9997 | 0.113955 | 0.090411 | -0.825068 |
9998 | 0.870587 | -1.327828 | -0.097523 |
9999 | -0.867561 | 0.149689 | -1.583496 |
9930 rows × 3 columns
1, 先指定异常值检测的标准. <绝对值大于三倍的标准偏差>
2, 把标准写成一个条件. <df.abs() > 3 * df.std()>
3, 再看是过滤行还是列. (df.abs() > 3 * df.std()).any(axis=1)
4, 最后再通过中括号中写条件写法把异常值过滤掉.
4. 抽样
使用.take()函数排序
可以借助np.random.permutation()函数随机排序
df
语文 | 数学 | 英语 | |
---|---|---|---|
张三 | 119 | 103 | 18 |
李四 | 5 | 103 | 89 |
王五 | 79 | 11 | 32 |
赵六 | 93 | 14 | 32 |
df.take([3,2,1,0])
语文 | 数学 | 英语 | |
---|---|---|---|
赵六 | 93 | 14 | 32 |
王五 | 79 | 11 | 32 |
李四 | 5 | 103 | 89 |
张三 | 119 | 103 | 18 |
df.take([2,1,0], axis=1)
英语 | 数学 | 语文 | |
---|---|---|---|
张三 | 18 | 103 | 119 |
李四 | 89 | 103 | 5 |
王五 | 32 | 11 | 79 |
赵六 | 32 | 14 | 93 |
随机抽样
# 无放回抽样
np.random.permutation([0,1,2,3])
array([0, 3, 1, 2])
# permutation和take结合可以实现无放回抽样
df.take(np.random.permutation([0,1,2,3]))
语文 | 数学 | 英语 | |
---|---|---|---|
李四 | 5 | 103 | 89 |
赵六 | 93 | 14 | 32 |
张三 | 119 | 103 | 18 |
王五 | 79 | 11 | 32 |
当DataFrame规模足够大时,直接使用np.random.randint()函数,就配合take()函数实现随机抽样
# 有放回抽样
# np.random.randint和take结合实现有放回抽样
df.take(np.random.randint(0,4, size=4))
语文 | 数学 | 英语 | |
---|---|---|---|
王五 | 79 | 11 | 32 |
王五 | 79 | 11 | 32 |
赵六 | 93 | 14 | 32 |
赵六 | 93 | 14 | 32 |
============================================
练习22:
假设有张三李四王老五的期中考试成绩ddd2,对着三名同学随机排序
============================================
# 无放回抽样
df.take(np.random.permutation([0,1,2,3])[:3])
语文 | 数学 | 英语 | |
---|---|---|---|
王五 | 79 | 11 | 32 |
李四 | 5 | 103 | 89 |
赵六 | 93 | 14 | 32 |
# 有放回抽样
df.take(np.random.randint(0,4, size=4)[:3])
语文 | 数学 | 英语 | |
---|---|---|---|
赵六 | 93 | 14 | 32 |
王五 | 79 | 11 | 32 |
王五 | 79 | 11 | 32 |
5. 数据聚合【重点】
数据聚合是数据处理的最后一步,通常是要使每一个数组生成一个单一的数值。
数据分类处理:
- 分组:先把数据分为几组
- 用函数处理:为不同组的数据应用不同的函数以转换数据
- 合并:把不同组得到的结果合并起来
数据分类处理的核心:
groupby()函数
如果想使用color列索引,计算price1的均值,可以先获取到price1列,然后再调用groupby函数,用参数指定color这一列
df = DataFrame({'color':['red','white','red','cyan','cyan','green','white','cyan'],
'price':np.random.randint(0,8,size = 8),
'weight':np.random.randint(50,55,size = 8)})
df
color | price | weight | |
---|---|---|---|
0 | red | 3 | 54 |
1 | white | 3 | 51 |
2 | red | 6 | 50 |
3 | cyan | 3 | 50 |
4 | cyan | 0 | 53 |
5 | green | 6 | 51 |
6 | white | 5 | 52 |
7 | cyan | 0 | 50 |
df.groupby(by='color')
<pandas.core.groupby.generic.DataFrameGroupBy object at 0x000000001145F710>
使用.groups属性查看各行的分组情况:
df.groupby(by='color').groups
{'cyan': Int64Index([3, 4, 7], dtype='int64'),
'green': Int64Index([5], dtype='int64'),
'red': Int64Index([0, 2], dtype='int64'),
'white': Int64Index([1, 6], dtype='int64')}
# 分组之后 进行聚合
# 先聚合再取值
df.groupby(by='color').sum()[['price']]
price | |
---|---|
color | |
cyan | 3 |
green | 6 |
red | 9 |
white | 8 |
# 先取值,再聚合 推荐写法.
price_sum = df.groupby(by='color')[['price']].sum()
df
color | price | weight | |
---|---|---|---|
0 | red | 3 | 54 |
1 | white | 3 | 51 |
2 | red | 6 | 50 |
3 | cyan | 3 | 50 |
4 | cyan | 0 | 53 |
5 | green | 6 | 51 |
6 | white | 5 | 52 |
7 | cyan | 0 | 50 |
df.merge(price_sum, left_on='color', right_index=True, suffixes=['', '_sum'])
color | price | weight | price_sum | |
---|---|---|---|---|
0 | red | 3 | 54 | 9 |
2 | red | 6 | 50 | 9 |
1 | white | 3 | 51 | 8 |
6 | white | 5 | 52 | 8 |
3 | cyan | 3 | 50 | 3 |
4 | cyan | 0 | 53 | 3 |
7 | cyan | 0 | 50 | 3 |
5 | green | 6 | 51 | 6 |
数据聚合的步骤
1, 分组, 找到分组的列
2, 聚合, 执行聚合操作,sum, mean, max, min
3, 合并, 把聚合的结果合并到原始表中.
============================================
练习23:
假设菜市场张大妈在卖菜,有以下属性:
菜品(item):萝卜,白菜,辣椒,冬瓜
颜色(color):白,青,红
重量(weight)
价格(price)
- 要求以属性作为列索引,新建一个ddd
- 对ddd进行聚合操作,求出颜色为白色的价格总和
- 对ddd进行聚合操作,求出萝卜的所有重量(包括白萝卜,胡萝卜,青萝卜)以及平均价格
- 使用merge合并总重量及平均价格
============================================
ddd = DataFrame({'item': ['萝卜', '萝卜','萝卜', '白菜', '白菜','辣椒','辣椒','辣椒', '冬瓜', '冬瓜'],
'color': ['白', '红', '青', '青', '白', '青', '红', '白', '青', '白'],
'weight': [60, 70, 40, 50, 60, 100, 80, 20, 200, 150],
'price': [2.68, 3.98, 4.98, 1.28, 1.58, 7.98, 8.88, 12.28, 1.28, 1.58]
})
ddd
item | color | weight | price | |
---|---|---|---|---|
0 | 萝卜 | 白 | 60 | 2.68 |
1 | 萝卜 | 红 | 70 | 3.98 |
2 | 萝卜 | 青 | 40 | 4.98 |
3 | 白菜 | 青 | 50 | 1.28 |
4 | 白菜 | 白 | 60 | 1.58 |
5 | 辣椒 | 青 | 100 | 7.98 |
6 | 辣椒 | 红 | 80 | 8.88 |
7 | 辣椒 | 白 | 20 | 12.28 |
8 | 冬瓜 | 青 | 200 | 1.28 |
9 | 冬瓜 | 白 | 150 | 1.58 |
ddd.groupby(by='color')[['price']].sum()
price | |
---|---|
color | |
白 | 18.12 |
红 | 12.86 |
青 | 15.52 |
weight_sum = ddd.groupby(by='item')[['weight']].sum()
price_mean = ddd.groupby(by='item')[['price']].mean()
price_mean
price | |
---|---|
item | |
冬瓜 | 1.430000 |
白菜 | 1.430000 |
萝卜 | 3.880000 |
辣椒 | 9.713333 |
ddd = ddd.merge(weight_sum, left_on='item', right_index=True, suffixes=['', '_sum'])
ddd.merge(price_mean, left_on='item', right_index=True, suffixes=['', '_mean'])
item | color | weight | price | weight_sum | price_mean | |
---|---|---|---|---|---|---|
0 | 萝卜 | 白 | 60 | 2.68 | 170 | 3.880000 |
1 | 萝卜 | 红 | 70 | 3.98 | 170 | 3.880000 |
2 | 萝卜 | 青 | 40 | 4.98 | 170 | 3.880000 |
3 | 白菜 | 青 | 50 | 1.28 | 110 | 1.430000 |
4 | 白菜 | 白 | 60 | 1.58 | 110 | 1.430000 |
5 | 辣椒 | 青 | 100 | 7.98 | 200 | 9.713333 |
6 | 辣椒 | 红 | 80 | 8.88 | 200 | 9.713333 |
7 | 辣椒 | 白 | 20 | 12.28 | 200 | 9.713333 |
8 | 冬瓜 | 青 | 200 | 1.28 | 350 | 1.430000 |
9 | 冬瓜 | 白 | 150 | 1.58 | 350 | 1.430000 |
6.0 高级数据聚合
可以使用pd.merge()函数将聚合操作的计算结果添加到df的每一行
使用groupby分组后调用加和等函数进行运算,让后最后可以调用add_prefix(),来修改列名
price_mean = price_mean.add_prefix('mean_')
# 添加后缀
price_mean = price_mean.add_suffix('_mean')
ddd.merge(price_mean, left_on='item', right_index=True)
item | color | weight | price | weight_sum | price_mean | |
---|---|---|---|---|---|---|
0 | 萝卜 | 白 | 60 | 2.68 | 170 | 3.880000 |
1 | 萝卜 | 红 | 70 | 3.98 | 170 | 3.880000 |
2 | 萝卜 | 青 | 40 | 4.98 | 170 | 3.880000 |
3 | 白菜 | 青 | 50 | 1.28 | 110 | 1.430000 |
4 | 白菜 | 白 | 60 | 1.58 | 110 | 1.430000 |
5 | 辣椒 | 青 | 100 | 7.98 | 200 | 9.713333 |
6 | 辣椒 | 红 | 80 | 8.88 | 200 | 9.713333 |
7 | 辣椒 | 白 | 20 | 12.28 | 200 | 9.713333 |
8 | 冬瓜 | 青 | 200 | 1.28 | 350 | 1.430000 |
9 | 冬瓜 | 白 | 150 | 1.58 | 350 | 1.430000 |
可以使用transform和apply实现相同功能
在transform或者apply中传入函数即可
ddd.groupby(by='item').transform(sum)
color | weight | price | weight_sum | |
---|---|---|---|---|
0 | 白红青 | 170 | 11.64 | 510 |
1 | 白红青 | 170 | 11.64 | 510 |
2 | 白红青 | 170 | 11.64 | 510 |
3 | 青白 | 110 | 2.86 | 220 |
4 | 青白 | 110 | 2.86 | 220 |
5 | 青红白 | 200 | 29.14 | 600 |
6 | 青红白 | 200 | 29.14 | 600 |
7 | 青红白 | 200 | 29.14 | 600 |
8 | 青白 | 350 | 2.86 | 700 |
9 | 青白 | 350 | 2.86 | 700 |
ddd.groupby(by='item').apply(sum)
item | color | weight | price | weight_sum | |
---|---|---|---|---|---|
item | |||||
冬瓜 | 冬瓜冬瓜 | 青白 | 350 | 2.86 | 700 |
白菜 | 白菜白菜 | 青白 | 110 | 2.86 | 220 |
萝卜 | 萝卜萝卜萝卜 | 白红青 | 170 | 11.64 | 510 |
辣椒 | 辣椒辣椒辣椒 | 青红白 | 200 | 29.14 | 600 |
============================================
练习24:
使用transform与apply实现练习23的功能
============================================