Python 熊猫适用,但仅适用于满足条件的行
我想使用PandasPython 熊猫适用,但仅适用于满足条件的行,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”中
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
值。对吗?这是一个只选择非零值的布尔掩码。您可以在此处阅读更多内容: