你能告诉我什么时候使用这些矢量化方法和基本的例子吗?

我看到map是一个系列方法,而其余的是DataFrame方法。我对apply和applymap方法感到困惑。为什么我们有两个方法来应用一个函数到一个数据帧?再一次,简单的例子说明用法将是伟大的!


当前回答

apply工作在数据帧的行/列基础上 applymap在DataFrame上按元素工作 map在Series上按元素工作


直接摘自Wes McKinney的Python for Data Analysis一书,第132页(我强烈推荐这本书):

另一个常见操作是将一维数组上的函数应用到每一列或行。DataFrame的apply方法是这样做的:

In [116]: frame = DataFrame(np.random.randn(4, 3), columns=list('bde'), index=['Utah', 'Ohio', 'Texas', 'Oregon'])

In [117]: frame
Out[117]: 
               b         d         e
Utah   -0.029638  1.081563  1.280300
Ohio    0.647747  0.831136 -1.549481
Texas   0.513416 -0.884417  0.195343
Oregon -0.485454 -0.477388 -0.309548

In [118]: f = lambda x: x.max() - x.min()

In [119]: frame.apply(f)
Out[119]: 
b    1.133201
d    1.965980
e    2.829781
dtype: float64

许多最常见的数组统计(如sum和mean)是DataFrame方法, 所以没有必要使用apply。

也可以使用元素级Python函数。假设您希望从帧中的每个浮点值计算一个格式化字符串。你可以用applymap:

In [120]: format = lambda x: '%.2f' % x

In [121]: frame.applymap(format)
Out[121]: 
            b      d      e
Utah    -0.03   1.08   1.28
Ohio     0.65   0.83  -1.55
Texas    0.51  -0.88   0.20
Oregon  -0.49  -0.48  -0.31

命名为applymap的原因是Series有一个map方法用于应用一个按元素划分的函数:

In [122]: frame['e'].map(format)
Out[122]: 
Utah       1.28
Ohio      -1.55
Texas      0.20
Oregon    -0.31
Name: e, dtype: object

其他回答

原因:

下面的示例显示apply和applymap应用到一个DataFrame。

map函数只能应用在Series上。不能在DataFrame上应用map。

需要记住的是,apply可以做任何applymap可以做的事情,但apply有额外的选项。

X因子选项是:axis和result_type,其中result_type仅在axis=1时有效(对于列)。

df = DataFrame(1, columns=list('abc'),
                  index=list('1234'))
print(df)

f = lambda x: np.log(x)
print(df.applymap(f)) # apply to the whole dataframe
print(np.log(df)) # applied to the whole dataframe
print(df.applymap(np.sum)) # reducing can be applied for rows only

# apply can take different options (vs. applymap cannot)
print(df.apply(f)) # same as applymap
print(df.apply(sum, axis=1))  # reducing example
print(df.apply(np.log, axis=1)) # cannot reduce
print(df.apply(lambda x: [1, 2, 3], axis=1, result_type='expand')) # expand result

作为旁注,不应将Series映射函数与Python映射函数混淆。

第一个应用在Series上,用于映射值,第二个应用到可迭代对象的每个项。


最后,不要混淆dataframe apply方法和groupby apply方法。

@jeremiahbuddha提到apply适用于行/列,而applymap适用于元素。但似乎仍然可以使用apply进行元素计算....

frame.apply(np.sqrt)
Out[102]: 
               b         d         e
Utah         NaN  1.435159       NaN
Ohio    1.098164  0.510594  0.729748
Texas        NaN  0.456436  0.697337
Oregon  0.359079       NaN       NaN

frame.applymap(np.sqrt)
Out[103]: 
               b         d         e
Utah         NaN  1.435159       NaN
Ohio    1.098164  0.510594  0.729748
Texas        NaN  0.456436  0.697337
Oregon  0.359079       NaN       NaN

apply工作在数据帧的行/列基础上 applymap在DataFrame上按元素工作 map在Series上按元素工作


直接摘自Wes McKinney的Python for Data Analysis一书,第132页(我强烈推荐这本书):

另一个常见操作是将一维数组上的函数应用到每一列或行。DataFrame的apply方法是这样做的:

In [116]: frame = DataFrame(np.random.randn(4, 3), columns=list('bde'), index=['Utah', 'Ohio', 'Texas', 'Oregon'])

In [117]: frame
Out[117]: 
               b         d         e
Utah   -0.029638  1.081563  1.280300
Ohio    0.647747  0.831136 -1.549481
Texas   0.513416 -0.884417  0.195343
Oregon -0.485454 -0.477388 -0.309548

In [118]: f = lambda x: x.max() - x.min()

In [119]: frame.apply(f)
Out[119]: 
b    1.133201
d    1.965980
e    2.829781
dtype: float64

许多最常见的数组统计(如sum和mean)是DataFrame方法, 所以没有必要使用apply。

也可以使用元素级Python函数。假设您希望从帧中的每个浮点值计算一个格式化字符串。你可以用applymap:

In [120]: format = lambda x: '%.2f' % x

In [121]: frame.applymap(format)
Out[121]: 
            b      d      e
Utah    -0.03   1.08   1.28
Ohio     0.65   0.83  -1.55
Texas    0.51  -0.88   0.20
Oregon  -0.49  -0.48  -0.31

命名为applymap的原因是Series有一个map方法用于应用一个按元素划分的函数:

In [122]: frame['e'].map(format)
Out[122]: 
Utah       1.28
Ohio      -1.55
Texas      0.20
Oregon    -0.31
Name: e, dtype: object

apply和applymap之间的区别可能是最简单的解释:

Apply将整个列作为参数,然后将结果分配给该列

Applymap将单独的单元格值作为参数,并将结果分配回该单元格。

注意:如果apply返回单个值,你将得到这个值而不是赋值后的列,最终将只有一行而不是矩阵。

我只是想指出一点,我在这方面有过一些挣扎

def f(x):
    if x < 0:
        x = 0
    elif x > 100000:
        x = 100000
    return x

df.applymap(f)
df.describe()

这不会修改数据帧本身,必须重新分配:

df = df.applymap(f)
df.describe()