Python 熊猫适用,但仅适用于满足条件的行

Python 熊猫适用,但仅适用于满足条件的行,python,pandas,dataframe,apply,Python,Pandas,Dataframe,Apply,我想使用Pandasdf.apply,但仅适用于某些行 举个例子,我想做这样的事情,但我的实际问题有点复杂: import pandas as pd import math z = pd.DataFrame({'a':[4.0,5.0,6.0,7.0,8.0],'b':[6.0,0,5.0,0,1.0]}) z.where(z['b'] != 0, z['a'] / z['b'].apply(lambda l: math.log(l)), 0) 在本例中,我想要的是每行“a”中的值除以“b”中

我想使用Pandas
df.apply
,但仅适用于某些行

举个例子,我想做这样的事情,但我的实际问题有点复杂:

import pandas as pd
import math
z = pd.DataFrame({'a':[4.0,5.0,6.0,7.0,8.0],'b':[6.0,0,5.0,0,1.0]})
z.where(z['b'] != 0, z['a'] / z['b'].apply(lambda l: math.log(l)), 0)

在本例中,我想要的是每行“a”中的值除以“b”中值的日志,对于“b”为0的行,我只想返回0。

您可以在lambda函数中使用if语句

z['c'] = z.apply(lambda row: 0 if row['b'] in (0,1) else row['a'] / math.log(row['b']), axis=1)
我还排除了1,因为log(1)是零

输出:

   a  b         c
0  4  6  2.232443
1  5  0  0.000000
2  6  5  3.728010
3  7  0  0.000000
4  8  1  0.000000

如果输入值为0,可以使用带条件的lambda返回0,并跳过整个
where
子句:

z['c'] = z.apply(lambda x: math.log(x.b) if x.b > 0 else 0, axis=1)

您还必须将结果分配到一个新列(
z['c']
)。

其他答案非常好,但我想我应该添加一种在某些情况下更快的方法-使用广播和掩蔽来实现相同的结果:

import numpy as np

mask = (z['b'] != 0)
z_valid = z[mask]

z['c'] = 0
z.loc[mask, 'c'] = z_valid['a'] / np.log(z_valid['b'])

特别是对于非常大的数据帧,这种方法通常比基于
apply()

的解决方案要快,希望这能有所帮助。它简单易读

df['c']=df['b'].apply(lambda x: 0 if x ==0 else math.log(x))

我知道我在这里比赛迟到了,但为什么需要指定axis=1?它不是在语法中指定的吗?为什么axis=1而不是0?@Windstorm1981请参见“axis”:因此,此遮罩遮住了您不想要的值。在这种情况下,您正在“选择”那些不是零的
z
值。对吗?这是一个只选择非零值的布尔掩码。您可以在此处阅读更多内容: