5-3 数据迭代和函数应用

1 数据迭代

数据迭代和数据遍历都是按照某种顺序逐个对数据进行访问和操作,在Python中大多由for语句来引导。Pandas中的迭代操作可以将数据按行或者按列遍历

1.1 迭代Series

Series本身是一个可迭代对象,Series df.name.values返回array结构数据可用于迭代,不过可直接对Series使用for语句来遍历它的值:

# 迭代指定的列
for i in df.name:    
    print(i)

迭代索引和指定的多列,使用Python内置的zip函数将其打包为可迭代的zip对象:

# 迭代索引和指定的两列
for i,n,q in zip(df.index, df.name, df.Q1):    
    print(i,n, q)

1.2 df.iterrows()

df.iterrows()生成一个可迭代对象,将DataFrame行作为(索引,行数据)组成的Series数据对进行迭代。在for语句中需要两个变量来承接数据:一个为索引变量,即使索引在迭代中不会使用(这种情况可用useless作为变量名);另一个为数据变量,读取具体列时,可以使用字典的方法和对象属性的方法。

# 迭代,使用name、Q1数据
for index, row in df.iterrows():   
     print(index,row['name'], row.Q1)

df.iterrows()是最常用、最方便的按行迭代方法。

1.3  按列迭代

如需要迭代一个DataFrame的列,可以直接对DataFrame迭代,会循环得到列名:

# 直接对DataFrame迭代
for column in df:    
    print(column)

再利用df [列名]的方法迭代列:

# 依次取出每个列
for column in df:    
    print(df[column])# 可对每个列的内容进行迭代
for column in df:    
    for i in df[column]:        
        print(i)# 可以迭代指定列
for i in df.name:    
print(i)# 只迭代想要的列
l = ['name', 'Q1']
cols = df.columns.intersection(l)
for col in cols:    
    print(col)

2 函数应用

pipe():应用在整个DataFrame或Series上。
apply():应用在DataFrame的行或列中,默认为列。
applymap():应用在DataFrame的每个元素中。
map():应用在Series或DataFrame的一列的每个元素中。

2.1 pipe()

Pandas提供的pipe()叫作管道方法,它可以让我们写的分析过程标准化、流水线化,达到复用目标,它也是最近非常流行的链式方法的重要代表。DataFrame和Series都支持pipe()方法。pipe()的语法结构为df.pipe(<函数名>, <传给函数的参数列表或字典>)。

# 对df多重应用多个函数
f(g(h(df), arg1=a), arg2=b, arg3=c)

# 用pipe可以把它们连接起来
(df.pipe(h)
   .pipe(g, arg1=a)   
   .pipe(f, arg2=b, arg3=c)
)

# 以下是将'arg2'参数传给函数f,然后作为函数整体接受后面的参数
(df.pipe(h)   
   .pipe(g, arg1=a)   
   .pipe((f, 'arg2'), arg1=a, arg3=c) 
)

函数h传入df的值返回的结果作为函数g的第一个参数值,g同时还传入了参数arg1;再将返回结果作为函数f的第一个参数,最终得到计算结果,这个调用过程显得异常复杂。使用pipe改造后代码逻辑复杂度大大降低,通过链式调用pipe()方法,对数据进行层层处理,大大提高代码的可读性。

# 定义一个函数,给所有季度的成绩加n,然后增加平均数
# 其中n中要加的值为必传参数
def add_mean(rdf, n):    
    df = rdf.copy()    df = df.loc[:,'Q1':'Q4'].applymap(lambda x: x+n)    
    df['avg'] = df.loc[:,'Q1':'Q4'].mean(1)
    return df
# 调用
df.pipe(add_mean, 100)

2.2 apply()

apply()可以对DataFrame按行和列(默认)进行函数处理,也支持Series。如果是Series,逐个传入具体值,DataFrame逐行或逐列传入。

# 将name全部变为小写
df.name.apply(lambda x: x.lower())

需要计算每个季度的平均成绩,计算方法为去掉一个最高分和一个最低分,剩余成绩的平均值为最终的平均分。

# 去掉一个最高分和一个最低分再算出平均分
def my_mean(s):    
    max_min_ser = pd.Series([-s.max(), -s.min()])    
    return s.append(max_min_ser).sum()/(s.count()-2)
# 对数字列应用函数
df.select_dtypes(include='number').apply(my_mean)

总结一下,apply()可以应用的函数类型如下:

df.apply(fun) # 自定义
df.apply(max) # Python内置函数
df.apply(lambda x: x*2) # lambda
df.apply(np.mean) #NumPy等其他库的函数
df.apply(pd.Series.first_valid_index) # Pandas自己的函数

2.3 applymap()

df.applymap()可实现元素级函数应用,即对DataFrame中所有的元素(不包含索引)应用函数处理

使用lambda时,变量是指每一个具体的值。

# 计算数据的长度
def mylen(x):    
    return len(str(x))

df.applymap(lambda x:mylen(x)) # 应用函数
df.applymap(mylen) # 效果同上

2.4 map()

map()根据输入对应关系映射值返回最终数据,用于Series对象或DataFrame对象的一列。传入的值可以是一个字典,键为原数据值,值为替换后的值。可以传入一个函数(参数为Series的每个值),还可以传入一个字符格式化表达式来格式化数据内容。

df.team.map({'A':'一班', 'B':'二班','C':'三班', 'D':'四班',}) # 枚举替换
df.team.map('I am a {}'.format)
df.team.map('I am a {}'.format, na_action='ignore')
t = pd.Series({'six': 6., 'seven': 7.})
s.map(t)# 应用函数
def f(x):    
   return len(str(x))
df['name'].map(f)

2.5 agg()

agg()一般用于使用指定轴上的一项或多项操作进行汇总,可以传入一个函数或函数的字符,还可以用列表的形式传入多个函数。

# 每列的最大值
df.agg('max')
# 将所有列聚合产生sum和min两行df.agg(['sum', 'min'])
# 序列多个聚合
df.agg({'Q1' : ['sum','min'], 'Q2' : ['min', 'max']})# 分组后聚合
df.groupby('team').agg('max')
df.Q1.agg(['sum', 'mean'])

def mymean(x):    
    return x.mean()
df.Q2.agg(['sum', mymean])

另外,agg()还支持传入函数的位置参数和关键字参数,支持每个列分别用不同的方法聚合,支持指定轴的方向。

# 每列使用不同的方法进行聚合
df.agg(a=('Q1',max),       
       b=('Q2','min'),       
       c=('Q3',np.mean),       
       d=('Q4',lambda s:s.sum()+1)      
      )# 按行聚合
df.loc[:,'Q1':].agg("mean", axis="columns")
# 利用pd.Series.add方法对所有数据加分,other是add方法的参数
df.loc[:,'Q1':].agg(pd.Series.add, other=10)

2.6 transform()

DataFrame或Series自身调用函数并返回一个与自身长度相同的数据。

df.transform(lambda x: x*2) # 应用匿名函数
df.transform([np.sqrt, np.exp]) # 调用多个函数
df.transform([np.abs, lambda x: x + 1])
df.transform({'A': np.abs, 'B': lambda x: x + 1})
df.transform('abs')df.transform(lambda x: x.abs())

2.7 copy()

类似于Python中copy()函数,df.copy()方法可以返回一个新对象,这个新对象与原对象没有关系。
当deep = True(默认)时,将创建一个新对象,其中包含调用对象的数据和索引的副本。对副本数据或索引的修改不会反映在原始对象中。当deep = False时,将创建一个新对象而不复制调用对象的数据或索引(仅复制对数据和索引的引用)。原始数据的任何更改都将对浅拷贝的副本进行同步更改,反之亦然。

s = pd.Series([1, 2], index=["a", "b"])
s_1 = s
s_copy = s.copy()
s_1 is s # True
s_copy is s # False

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
该资源内项目源码是个人的课程设计、毕业设计,代码都测试ok,都是运行成功后才上传资源,答辩评审平均分达到96分,放心下载使用! ## 项目备注 1、该资源内项目代码都经过测试运行成功,功能ok的情况下才上传的,请放心下载使用! 2、本项目适合计算机相关专业(如计科、人工智能、通信工程、自动化、电子信息等)的在校学生、老师或者企业员工下载学习,也适合小白学习进阶,当然也可作为毕设项目、课程设计、作业、项目初期立项演示等。 3、如果基础还行,也可在此代码基础上进行修改,以实现其他功能,也可用于毕设、课设、作业等。 下载后请首先打开README.md文件(如有),仅供学习参考, 切勿用于商业用途。 该资源内项目源码是个人的课程设计,代码都测试ok,都是运行成功后才上传资源,答辩评审平均分达到96分,放心下载使用! ## 项目备注 1、该资源内项目代码都经过测试运行成功,功能ok的情况下才上传的,请放心下载使用! 2、本项目适合计算机相关专业(如计科、人工智能、通信工程、自动化、电子信息等)的在校学生、老师或者企业员工下载学习,也适合小白学习进阶,当然也可作为毕设项目、课程设计、作业、项目初期立项演示等。 3、如果基础还行,也可在此代码基础上进行修改,以实现其他功能,也可用于毕设、课设、作业等。 下载后请首先打开README.md文件(如有),仅供学习参考, 切勿用于商业用途。
该资源内项目源码是个人的课程设计、毕业设计,代码都测试ok,都是运行成功后才上传资源,答辩评审平均分达到96分,放心下载使用! ## 项目备注 1、该资源内项目代码都经过测试运行成功,功能ok的情况下才上传的,请放心下载使用! 2、本项目适合计算机相关专业(如计科、人工智能、通信工程、自动化、电子信息等)的在校学生、老师或者企业员工下载学习,也适合小白学习进阶,当然也可作为毕设项目、课程设计、作业、项目初期立项演示等。 3、如果基础还行,也可在此代码基础上进行修改,以实现其他功能,也可用于毕设、课设、作业等。 下载后请首先打开README.md文件(如有),仅供学习参考, 切勿用于商业用途。 该资源内项目源码是个人的课程设计,代码都测试ok,都是运行成功后才上传资源,答辩评审平均分达到96分,放心下载使用! ## 项目备注 1、该资源内项目代码都经过测试运行成功,功能ok的情况下才上传的,请放心下载使用! 2、本项目适合计算机相关专业(如计科、人工智能、通信工程、自动化、电子信息等)的在校学生、老师或者企业员工下载学习,也适合小白学习进阶,当然也可作为毕设项目、课程设计、作业、项目初期立项演示等。 3、如果基础还行,也可在此代码基础上进行修改,以实现其他功能,也可用于毕设、课设、作业等。 下载后请首先打开README.md文件(如有),仅供学习参考, 切勿用于商业用途。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值