如何对Pandas数据框架中的每个单元格应用一个函数?

161 阅读2分钟

问题的提出

给出以下数据框架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/)来 "即时 "创建一个函数对象。