文章目录
pandas
什么是pandas
pandas:Python Data Analysis Library,是基于 Numpy 的一种高效地操作大型数据集的工具。
panda 是一个开源的,为 Python 编程语言提供高性能、易于使用的数据结构和数据分析工具。
pandas 能够解决什么问题?
- pandas 能够在 Python 中执行整个数据分析工作流,而不必切换到更特定于领域的语言,如 R。
- 结合优秀的IPython工具包和其他库,使用Python进行数据分析的环境在性能、生产率和协作能力方面都非常出色。
- pandas 除了线性回归和面板回归外,panda没有实现显著的建模功能;为此,请参阅statsmodels和scikit-learn。要使Python成为一流的统计建模环境,还需要做更多的工作,但是我们正在朝着这个目标前进。
pandas 由以下元素组成:
- 一组带标签的数组数据结构,其主要结构是Series和DataFrame。
- 索引对象,支持简单 axis 索引和多级/分层 axis 索引。
- 日期范围生成(date_range)和自定义日期偏移量,支持自定义频率的实现。
- 从平面文件(CSV, delimited, Excel 2003)加载表格数据,并以 PyTables/HDF5 格式快速高效的保存和加载 pandas 对象。
- 内存效率高的 “sparse” 标准数据结构版本,用于存储大部分丢失的数据或大部分不变的数据(一些固定值)。
- 移动窗口统计量(滚动平均值、滚动标准差等)。
pandas 数据结构:
- Series:相同数据结构的一维数组。
- Dataframe:一般是 2D label,大小可变的表格结构,可能具有异种类型的列。可把它看作 excel 来帮助理解。
- Panel:一般3D标记,大小可变数组。
所有 Pandas 数据结构是值可变的(可以更改),除了Series 都是大小可变的。Series 是大小不变的。
# 数据分析三剑客,即三个模块
# numpy pandas matplotlib
# 前两个属于数据分析,展示数据,第三个是画图
import numpy as np
import pandas as pd
from pandas import Series,DataFrame
import matplotlib.pyplot as plt
# 如果在使用 plt.imshow() 显示图片时,没有显示出来图片,可以添加下面魔法指令
%matplotlib inline
附件
本笔记代码文件见 005-pandas附件
1. Series
Series是一种类似于一维数组的对象,由下面两个部分组成:
- values:数据(ndarray类型)
- index:索引
1.1 Series的创建
两种创建方式:
(1) 由列表或 numpy 数组(ndarray)创建
默认索引为 0 到 N-1 的整数型索引
也可以通过设置 index 参数指定索引
# 创建:使用 列表
s = Series([18,22,15,33])
# 创建:使用 ndarray
s = Series(data = np.random.randint(0,100,size=8))
# 设置索引 index
l = [1,2,3,4]
s = Series(l,index = ['a','b','c','d'])
# 根据索引获取元素
# 没有手动设置 index 时,使用整数索引获取,如 s[2]
# 手动设置了 index 索引时,可以使用自然数索引,也可以使用手动设置的索引值获取,如 s[2]、s['c']
# 获取多个索引对应的值时
s1[['a']]
s1[['a','b']]
s1[[0,1]]
# 指定 name
s1 = Series(np.random.randint(0,150,size = 8),index = list('abcdefgh'),name='数学')
注意:对 Series 元素的改变也会改变原来的 ndarray 对象中的元素。
(2) 由字典创建
key 将作为索引
# 创建
s = Series({'语文':150,'数学':130})
# 获取
s['数学'] or s[1]
v = s.values
v[0]
1.2 Series的索引和切片
可以使用中括号取单个索引(此时返回的是元素),或者中括号里一个列表取多个索引(此时返回的仍然是一个Series类型)
s[2]、s['c']
s1[['a']]
s1[['a','b']]
s1[[0,1]]
索引分为两种索引:显示索引和隐式索引
(loc = location 位置,定位)
(1)显示索引
- 使用 index 中的元素作为索引值
- 使用.loc[](推荐)
注意,显示切片时是闭区间
s1['a']
s1.loc['f']
s1.loc[['f']]
s1.loc[['f','a']]
# series显示切片,是闭区间
s1['a':'e']
s2.loc['a':'f']
(2) 隐式索引:
- 使用默认自然充数作为索引值
- 使用.iloc[](推荐)
注意,切片时是半开区间(左闭右开)
s2[1]
s2[[1,2]]
s2.iloc[4]
s2.iloc[[1,3]]
# Series隐式切片,相当于 ndarray 切片,左闭右开
s2[0:4]
s2.iloc[0:4]
1.3 Series 基本用法
(1)属性
shape,size,index,values等
s3.shape
s3.size
s3.index
s3.values
# 设置Series index
s3.index = list('ABCDEFGH')
注意:index必须全部设置,不能部分设置
(2)head(),tail()方法
head():默认查看前5个数据,设置参数 n 可以指定查看的个数
tail():默认查看后5个数据,设置参数 n 可以指定查看的个数
# 默认查看前5个数据,参数 n 可以指定查看的个数
# s3.head(n = 10)
s3.head()
(3)sum()
即使元素中有nan,None,sum()仍然可以使用,它会跳过nan,None值
s6 = Series({'数学':120,'英语':np.nan,'化学':None,'物理':100,'语文':80})
# 即使数据中存在空值,sum()仍然可以自动跳过空值进行计算
s6.sum() # 300.0
(4) isnull()、notnull()
可以使用pd.isnull(),pd.notnull(),或自带isnull(),notnull()函数检测缺失数据
# isnull():是否有空值,有空值返回 True,否则返回 False
s6.isnull()
# notnull():检查 Series 中哪些值不为空
cond = s6.notnull()
# 如果传给 Series 的是 boolean 值,则 False 对应的将被删除
s6[cond]
1.5 Series的运算
(1) 适用于numpy的数组运算也适用于Series
s2 + 100
......
cond2 = s2 <= 100
s2[cond2] += 100
(2) Series之间的运算
索引相同的相加,不同的补NaN
s2:
a 142
b 235
c 250
d 239
e 109
f 278
g 107
h 109
s8:
A 38
b 77
c 64
D 20
E 1
s2 + s8:
A NaN
D NaN
E NaN
a NaN
b 312.0
c 314.0
d NaN
e NaN
f NaN
g NaN
h NaN
# 消除 NaN
s2.add(s8,fill_value=0)
A 38.0
D 20.0
E 1.0
a 142.0
b 312.0
c 314.0
d 239.0
e 109.0
f 278.0
g 107.0
h 109.0
2. DataFrame
DataFrame 是用于存储表格数据的多维数据结构,可把它看作 excel 来帮助理解。
DataFrame 设计初衷是将 Series 的使用场景从一维拓展到多维。
DataFrame 既有行索引(index),也有列索引(columns)
2.1 DataFrame 的创建
1)传递一个字典来创建,key 作为列名,value 作为列数据
创建时,会自动加上行索引(自然数)
df = DataFrame({'数学':[95,82,90,89,93],
'Python':np.random.randint(0,100,size=5),
'语文':[73,60,65,77,62]},
index = ['张三','李四','王五','赵六','周七'],
columns=['数学','Python','语文'])
df 结果:
数学 Python 语文
张三 95 25 73
李四 82 56 60
王五 90 68 65
赵六 89 71 77
周七 93 54 62
2)通过 ndarray
df2 = DataFrame(data = np.random.randint(0,150,size = (5,4)),
index = list('abcde'),
columns=['身高','体重','工资','零花钱'])
df2 结果:
身高 体重 工资 零花钱
a 82 57 81 142
b 104 0 129 76
c 80 7 24 101
d 135 125 11 58
e 129 108 26 107
2.2 DataFrame属性
values、columns、index、shape
df.shape
df.columns
df.values
df.index
# 修改行索引值,索引必须全部列出
df.index = ['Mr.Zhang','李四','王五','赵六','Mr.Zhou']
2.3 DataFrame的索引
1) 对列进行索引
- 通过类似字典的方式
- 通过属性的方式
df2.身高
df2['体重']
df2[['体重','身高']]
2) 对行进行索引
- 使用.ix[]来进行行索引(既可以用默认的 自然数序号 进行索引,也可以用指定的 index 进行索引)
说明:ix[] 使用指定的 index 进行索引时,相当于 loc[]
使用自然序号时,相当于 iloc[]
- 使用.loc[]加 index 来进行行索引(如果没有显示指定 index,index 就是默认的自然数序号)
注意:对于一维数据可以都使用,对于多维数据最好使用显示指定的index
(所以 loc[] 推荐使用显示的 index 进行索引)
- 使用.iloc[]加 默认的 自然数序号 来进行行索引
注意:自然序号表示【所有】行or列的排序号
df2.ix['a']
df2.ix[1]
df2.loc['a']
df2.loc[['a','c']]
df2.iloc[0]
df2.iloc[[0,3]]
3)对元素索引的方法
- 使用列索引
- 使用行索引
- 使用values属性
df2:
身高 体重 工资 零花钱
a 82 57 81 142
b 104 0 129 76
c 80 7 24 101
d 135 125 11 58
e 129 108 26 107
# 使用列索引:先获取列,再获取行
df2['身高']['c'] # 80
# 使用行索引:先获取行,再获取列
df2.ix[3]['体重'] # 125
df2.ix['d']['体重'] # 125
df2.ix[3,'体重'] # 125
df2.loc['b']['工资'] # 129
df2.loc['c','身高'] # 80
df2.iloc[1]['身高'] # 104
# 使用 values 获取元素
df8 = df2.values
df8[2,1]
2.4 DataFrame 切片
1)行切片
df2.ix['a':'c']
df2.loc['a':'c']
df2.iloc[0:3]
身高 体重 工资 零花钱
a 82 57 81 142
b 104 0 129 76
c 80 7 24 101
2)列切片
df2.ix[1:,1:3]
df2.loc['b':,'体重':'工资']
df2.iloc[1:,1:3]
体重 工资
b 0 129
c 7 24
d 125 11
e 108 26
2.5 DataFrame 的运算
1)DataFrame之间的运算
运算时,相同的 index 和 columns 的元素进行运算,不同的用 NaN(也可指定 fill_value 值)
注意: fill_value:填充值,如果运算的两个元素只有一个数据丢失(为NaN),则可以用 fill_value 填充,如果两个都丢失,那么最后结果就丢失了,则不能填充,
# 下面例子只是演示怎么相加,未必能正常得出结果
df + df2
df.add(df2,fill_value=0)
2)Series 与 DataFrame 之间的运算
# axis 表示相加的方向,index(或0) 是行索引,按水平方向相加,coulumns同理
df3.add(s2,axis = 'index')
df3.add(s2,axis = 0)
3. 处理丢失数据
3.1 None 和 np.nan
import numpy as np
import pandas as pd
from pandas import Series,DataFrame
有两种丢失数据:None 和 np.nan
None是Python自带的,其类型为python object。因此,None不能参与到任何计算中。
np.nan是浮点类型,能参与到计算中。但计算的结果总是NaN。但可以使用np.nan*()函数来计算nan,此时视nan为0。
pandas中None与np.nan都视作np.nan
3.2 pandas中None与np.nan的操作
isnull():检测是否为None/nan
notnull():检测是否不为None/nan
dropna(): 过滤丢失数据(None/nan)
fillna(): 填充丢失数据(None/nan)
# all() 判断行or列所有数据都必须是 True,函数结果才会返回 True,可以有 axis 参数
# any() 判断行or列中任何一个数据为 True,函数结果就会返回 True,可以有 axis 参数
df.isnull()
df.notnull()
df.notnull().any(axis=1)
df.notnull().all(axis=1)
(1)判断函数
isnull()
notnull()
(2) 过滤函数
dropna()
可以选择过滤的是行还是列(默认为行)
也可以选择过滤的方式 how = 'all'/'any',默认为 any
all:如果检测的数据所有的值都是NA,则过滤掉
any:如果检测的数据只要存在NA,就过滤掉
df.dropna(axis=1)
df.dropna()
df.dropna(how='all')
(3) 填充函数
fillna():填充,methond 默认为 None,axis 默认为 0
填充方式 method : {'backfill', 'bfill', 'pad', 'ffill', None}
前置填充:pad/ffill,将前一个合法的数据填充到后面
后置填充:bfill/backfill,将后一个合法的数据填充到前面
# axis 表示从前面行或列选择填充
df3:
English Python math
0 135.0 126.0 139.0
1 111.0 NaN 125.0
2 128.0 NaN NaN
3 93.0 99.0 66.0
# 前置填充
df3.fillna(method='ffill')
English Python math
0 135.0 126.0 139.0
1 111.0 126.0 125.0
2 128.0 126.0 125.0
3 93.0 99.0 66.0
# 后置填充
df3.fillna(method='bfill')
English Python math
0 135.0 126.0 139.0
1 111.0 99.0 125.0
2 128.0 99.0 66.0
3 93.0 99.0 66.0
# 后置填充,按列填充
df3.fillna(method='bfill',axis=1)
English Python math
0 135.0 126.0 139.0
1 111.0 125.0 125.0
2 128.0 NaN NaN
3 93.0 99.0 66.0
4. pandas 层次化索引
4.1 创建多层行/列索引
import numpy as np
import pandas as pd
from pandas import Series,DataFrame
(1)隐式构造
给 DataFrame 构造函数的 index/columns 参数传递两维或更多维(两个或更多个)的数组
》Series 创建多层索引
# Series 通过 index 创建多层行索引
s = Series(np.random.randint(0,150,size=6),
index = [['a','a','b','b','c','c'],['期中','期末','期中','期末','期中','期末']])
s 结果:
a 期中 124
期末 132
b 期中 118
期末 95
c 期中 58
期末 115
》给 DataFrame 创建多层行索引
d1 = DataFrame(np.random.randint(1,100,size=(4,3)),
index = [['a','a','b','b'],['期中','期末','期中','期末']],
columns=[['Math','English','Python']])
d1 结果:
Math English Python
a 期中 23 50 43
期末 33 23 34
b 期中 88 79 27
期末 73 71 58
》给 DataFrame 创建多层列索引
d2 = DataFrame(np.random.randint(1,100,size=(4,4)),
index = ['Math','English','Python','Java'],
columns=[['一年级','一年级','二年级','二年级'],['期中','期末','期中','期末']])
d2 结果:
一年级 二年级
期中 期末 期中 期末
Math 89 81 66 98
English 7 21 56 83
Python 85 14 25 38
Java 29 69 49 42
(2)显示构造
pd.MultiIndex
》使用数组:pd.MultiIndex.from_arrays()
df3 = DataFrame(np.random.randint(0,150,size=(4,6)),
index=list('东南西北'),
columns=pd.MultiIndex.from_arrays([['Python','Python','Math','Math','English','Englisth'],
['期中','期末','期中','期末','期中','期末']]))
》使用 tuple:pd.MultiIndex.from_tuples()
df4 = DataFrame(np.random.randint(0,150,size=(4,6)),
index=list('东南西北'),
columns=pd.MultiIndex.from_tuples([('Python','期中'),('Python','期末'),
('Math','期中'),('Math','期末'),
('En','期中'),('En','期末')]))
》使用 product:pd.MultiIndex.from_product() ------【最简单,推荐使用】
df5 = DataFrame(np.random.randint(0,150,size=(4,6)),
index=list('东南西北'),
columns=pd.MultiIndex.from_product([['Python','Math','En'],['期中','期末']]))
4.2 多层索引对象的索引与切片操作
1)索引
》对 Series 的操作
s.a
s.a.期末
s['b','期中']
s.ix['b','期中']
s.ix[0]
s.loc['a','期中']
s.iloc[0]
》对 DataFrame 的操作
df2['Python']
df2['Python','期末']
df2.Python.期末.南
df2['Python','期末']['南']
# 对行索引使用 ix[]、loc[]、iloc[]
df2.ix[0]
df2.loc['北']['Python']
df2.iloc[1]
2)切片
》对 Series 的操作
s['a':'b']
s.ix['a':'b']
s.ix[0:3]
s.loc['a':'b']
s.iloc[0:3]
》对 DataFrame 的操作
df2.loc['东':'西']
......
# 对列切片,先切行,再切列
df2.iloc[:,2:]
4.3 索引的堆
stack(level):将指定层级的列索引变成最后一级行索引,level 默认为 -1,即最后一层级
unstack(level):将指定层级的行索引变成最后一级列索引,level 默认为 -1
rq = DataFrame(np.random.randint(1,100,size=(8,8)),
index=pd.MultiIndex.from_product([['a','b'],['A','B'],['东','西']]),
columns=pd.MultiIndex.from_product([['一','二'],['one','two'],['1s','2s']]))
rq.stack()
rq.stack(level=1)
rq.unstack()
rq.unstack(level=1)
例:rq为
一 二
one two one two
1s 2s 1s 2s 1s 2s 1s 2s
a A 东 71 68 37 75 14 93 39 29
西 44 76 83 94 97 51 31 59
B 东 31 68 83 49 40 50 80 74
西 64 52 14 32 27 96 43 55
b A 东 76 20 10 57 50 94 49 85
西 8 28 23 58 84 56 73 44
B 东 23 91 31 52 81 35 58 32
西 9 19 82 77 4 56 93 63
执行 rq.stack()后
一 二
one two one two
a A 东 1s 71 37 14 39
2s 68 75 93 29
西 1s 44 83 97 31
2s 76 94 51 59
B 东 1s 31 83 40 80
2s 68 49 50 74
西 1s 64 14 27 43
2s 52 32 96 55
b A 东 1s 76 10 50 49
2s 20 57 94 85
西 1s 8 23 84 73
2s 28 58 56 44
B 东 1s 23 31 81 58
2s 91 52 35 32
西 1s 9 82 4 93
2s 19 77 56 63
5. 聚合操作
需要指定axis(index:0, columns:1),不指定时默认为 0,指定行计算列,指定列计算行
mean():平均值
std():方差
cumsum():累加求和
max():最大值
......
df7.mean()
6. pandas的拼接操作
pandas的拼接分为两种:
级联:pd.concat, pd.append
合并:pd.merge, pd.join
回顾:numpy的级联
# 生成2个3*3的矩阵,对其分别进行两个维度上的级联
nd = np.random.randint(0,10,size=(3,3))
nd 结果:
array([[5, 1, 8],
[4, 1, 6],
[6, 2, 5]])
np.concatenate([nd,nd])
级联结果:
array([[5, 1, 8],
[4, 1, 6],
[6, 2, 5],
[5, 1, 8],
[4, 1, 6],
[6, 2, 5]])
np.concatenate([nd,nd],axis = 1)
级联结果:
array([[5, 1, 8, 5, 1, 8],
[4, 1, 6, 4, 1, 6],
[6, 2, 5, 6, 2, 5]])
示例参见附件
6.1 级联
1)pd.concat(objs, axis=0, join='outer', join_axes=None, ignore_index=False, keys=None, levels=None, names=None, verify_integrity=False, copy=True)
(1)简单级联
单纯的连接在一起
注意index在级联时可以重复
(2)不匹配级联
有3种连接方式:
- 外连接:outer,直接连接(不做其他删减操作),不匹配的补NaN,(默认模式)
- 内连接:inner,只连接匹配的项(其他不匹配的擦除掉)
2)append():直接在后面追加
df1.append(df2)
6.2 合并
1)pd.merge(left, right, how='inner', on=None, left_on=None, right_on=None, left_index=False, right_index=False, sort=False, suffixes=('_x', '_y'), copy=True, indicator=False, validate=None)
要合并的行(或列)名称相同,且行(或列)的值也必须相同(共同的行或列进行合并)
默认为 inner(只会擦除完全不匹配的行or列)
- 一对一连接
- 多对一连接
- 多对多连接
- key 的规范化
使用 left_on/right_on = 显式指定哪一列为key,当有多个key相同时使用
注意:使用 left_on/right_on 条件是
第一个 DataFrame 最右边的列 和 第二个 DataFrame 最左边的列 要相同
第一个 DataFrame 就使用 left_on = 列名(表示这一列去连接第二个 DataFrame 的左边)
第二个 DataFrame 就使用 right_on = 列名(表示这一列去连接第一个 DataFrame 的右边)
- 内合并:inner,连接匹配的项(保留匹配项所在的行or列,其他完人一不匹配的擦除掉)
- 外合并:outer,直接连接(不做其他删减操作),不匹配的补NaN
6.3 列冲突的解决
当列冲突时,即有多个列名称相同时,需要使用on=来指定哪一个列作为匹配列,其他数据匹配的列使用suffixes指定冲突列名
7. pandas数据处理
7.1 删除重复元素
drop_duplicates(subset=None, keep='first', inplace=False):删除重复行
duplicate(subset=None, keep='first'):用于检测列元素,如果列元素不是第一次出现,该行就返回布尔值 True,否则返回 False
使用 duplicated() 函数检测重复的 [行],如果该行不是第一次出现,则为True,否则为 False
dq = DataFrame({'color':['red','orange','yellow'],'size':[30,50,30]})
dq ====》
color size
0 red 30
1 orange 50
2 yellow 30
dq.duplicated('size')
====》
0 False
1 False
2 True
dtype: bool
dq.drop_duplicates('size')
====》
color size
0 red 30
1 orange 50
df = DataFrame({'color':['white','red','white'],'size':[10,20,10]})
df
====》
color size
0 white 10
1 red 20
2 white 10
df.duplicated()
====》
0 False
1 False
2 True
dtype: bool
df.drop_duplicates()
====》
color size
0 white 10
1 red 20
7.2 映射
创建一个映射关系,将要替换的值和替换值一一对应,通常使用字典:
{
'old_ele1' : 'new_ele1',
'old_ele2' : 'new_ele2'
}
映射包含三种操作:
replace():用于替换元素
map():用于创建新列
rename():用于替换索引
(1) repalce()
df ====》
color size
0 white 10
1 red 20
2 white 10
# 确立对应关系
d = {'white':255,'red':128}
df2 = df.replace(d)
df2
====》
color size
0 255 10
1 128 20
2 255 10
replace还经常用来替换NaN元素,如
x ====》
color size
0 white NaN
1 red 20.0
2 white 10.0
y = {np.nan:1000}
x.replace(y)
====》
color size
0 white 1000.0
1 red 20.0
2 white 10.0
(2) map()
df2 = DataFrame(np.random.randint(0,150,size=(4,2)),
columns=['Python','Java'],
index=list('abcd'))
df2
====>
Python Java
a 60 90
b 13 119
c 20 80
d 149 64
df2['Math'] = df2['Python'].map(lambda x : x + 20)
df2
====>
Python Java Math
a 60 90 80
b 13 119 33
c 20 80 40
d 149 64 169
def level(x):
if x >= 100:
return '优秀'
elif x >= 80:
return '良好'
elif x >= 60:
return '及格'
else:
return '不及格'
df2['level'] = df2['Java'].map(level)
df2
====>
Python Java Math level
a 60 90 80 良好
b 13 119 33 优秀
c 20 80 40 良好
d 149 64 169 及格
(3) rename
df2 ====>
Python Java Math level
a 120 90 80 B
b 73 119 33 A
c 80 80 40 B
d 209 64 169 C
df2.rename({'a':'李'})
Python Java Math level
李 120 90 80 B
b 73 119 33 A
c 80 80 40 B
d 209 64 169 C
df2.rename({'level':'等级'},axis = 1)
Python Java Math 等级
a 120 90 80 B
b 73 119 33 A
c 80 80 40 B
d 209 64 169 C
7.3 异常值检测和过滤
使用 describe() 函数查看每一列的描述性统计量,再根据需求进行过滤(drop)
7.4 排序
take():根据给定的索引顺序排序
np.random.permutation():随机生成序列(列表)
df2 ====>
Python Java Math level
a 120 90 80 B
b 73 119 33 A
c 80 80 40 B
d 209 64 169 C
df2.take([3,2,1,0])
====》
Python Java Math level
d 209 64 169 C
c 80 80 40 B
b 73 119 33 A
a 120 90 80 B
df2.take(np.random.permutation(4))
====》
Python Java Math level
d 209 64 169 C
c 80 80 40 B
a 120 90 80 B
b 73 119 33 A
8. 数据聚合
数据分类处理:
分组:先把数据分为几组
用函数处理:为不同组的数据应用不同的函数以转换数据
合并:把不同组得到的结果合并起来
9. 高级数据聚合
df7 = DataFrame(data = {'item':['萝卜','白菜','西红柿','辣椒','冬瓜','萝卜','西红柿','西红柿','辣椒','冬瓜','萝卜'],
'seller':['李大妈','李大妈','李大妈','王大妈','王大妈','王大妈','王大妈','赵大妈','赵大妈','赵大妈','赵大妈'],
'price':np.random.randint(3,10,size=11)},columns=['item','seller','price'])
df7 ====》
item seller price
0 萝卜 李大妈 4
1 白菜 李大妈 5
2 西红柿 李大妈 7
3 辣椒 王大妈 7
4 冬瓜 王大妈 3
5 萝卜 王大妈 4
6 西红柿 王大妈 7
7 西红柿 赵大妈 3
8 辣椒 赵大妈 3
9 冬瓜 赵大妈 8
10 萝卜 赵大妈 8
# 按 item 分组,使用 transform() 保留原来的总行数,
df7.groupby(['item']).transform(sum)
seller price
0 李大妈王大妈赵大妈 16
1 李大妈 5
2 李大妈王大妈赵大妈 17
3 王大妈赵大妈 10
4 王大妈赵大妈 11
5 李大妈王大妈赵大妈 16
6 李大妈王大妈赵大妈 17
7 李大妈王大妈赵大妈 17
8 王大妈赵大妈 10
9 王大妈赵大妈 11
10 李大妈王大妈赵大妈 16
# groupby + apply:类似 sql 中的分组
df7.groupby(['item']).apply(sum)
item seller price
item
冬瓜 冬瓜冬瓜 王大妈赵大妈 11
白菜 白菜 李大妈 5
萝卜 萝卜萝卜萝卜 李大妈王大妈赵大妈 16
西红柿 西红柿西红柿西红柿 李大妈王大妈赵大妈 17
辣椒 辣椒辣椒 王大妈赵大妈 10
操作文件
import pandas as pd
# 返回的数据是DataFrame
df1 = pd.read_csv('../../data/president_heights.txt')
datas = df1.values