问题的提出
给出以下数据框架df
import pandas as pd
df = pd.DataFrame([{'A':1, 'B':2, 'C':2, 'D':4},
{'A':4, 'B':8, 'C':3, 'D':1},
{'A':2, 'B':7, 'C':1, 'D':2},
{'A':3, 'B':5, 'C':1, 'D':2}])
print(df)
'''
A B C D
0 1 2 2 4
1 4 8 3 1
2 2 7 1 2
3 3 5 1 2
'''
挑战:如何对DataFrame中的每个单元格应用一个函数 ?f
例如,你可能想应用一个函数,将所有奇数值替换为'odd' 。
import pandas as pd
df = pd.DataFrame([{'A':1, 'B':2, 'C':2, 'D':4},
{'A':4, 'B':8, 'C':3, 'D':1},
{'A':2, 'B':7, 'C':1, 'D':2},
{'A':3, 'B':5, 'C':1, 'D':2}])
def f(cell):
if cell%2 == 1:
return 'odd'
return cell
# ... <Apply Function f to each cell> ...
print(df)
'''
A B C D
0 odd 2 2 4
1 4 8 odd odd
2 2 odd odd 2
3 odd odd odd 2
'''
解决方案:DataFrame applymap()
Pandas DataFramedf.applymap() 方法返回一个新的DataFrame,其中函数f 被应用到原始DataFramedf 的每个单元格。你可以将任何函数对象作为单一参数传入df.applymap() ,可以定义为lambda表达式或普通函数。
例1:替换DataFrame中的奇数值
这里有一个例子,DataFrame的每个单元格都被检查是否为奇数值。如果是,就用字符串'odd' 。
def f(cell):
if cell%2 == 1:
return 'odd'
return cell
df_new = df.applymap(f)
print(df_new)
'''
A B C D
0 odd 2 2 4
1 4 8 odd odd
2 2 odd odd 2
3 odd odd odd 2
'''
例2:创建两个替换了偶数和奇数值的数据框架
一个稍微高级的例子使用两个lambda函数来创建两个新的DataFrames,其中一个有所有的奇数,另一个有所有的偶数值被替换。
import pandas as pd
df = pd.DataFrame([{'A':1, 'B':2, 'C':2, 'D':4},
{'A':4, 'B':8, 'C':3, 'D':1},
{'A':2, 'B':7, 'C':1, 'D':2},
{'A':3, 'B':5, 'C':1, 'D':2}])
df_even = df.applymap(lambda x: 'odd' if x%2 else x)
df_odd = df.applymap(lambda x: x if x%2 else 'even')
print(df_even)
'''
A B C D
0 odd 2 2 4
1 4 8 odd odd
2 2 odd odd 2
3 odd odd odd 2
'''
print(df_odd)
'''
A B C D
0 1 even even even
1 even even 3 1
2 even 7 1 even
3 3 5 1 even
'''
我们使用了a的概念 三元运算符来简洁地定义替换函数,使用关键字 [lambda](https://blog.finxter.com/python-ternary-lambda/)来 "即时 "创建一个函数对象。