Python np.vectorize的替代方案,以在pandas中应用函数

Python np.vectorize的替代方案,以在pandas中应用函数,python,pandas,numpy,dataframe,Python,Pandas,Numpy,Dataframe,假设我有这样一个数据帧: ID糖果包装错误 0 001无1无 10021无 2 003 1 1 040 3 004无1 040 4 005 11无 我想要一个这样的新专栏: 要跟进的ID Candy包装器错误原因 0 001无1无未制造的匹配糖果。 1 002 1无匹配包装未制造。 2 003 1 1040工厂故障。 3 004无1 040工厂故障。 4 005 11无 我一直使用np.vectorize来实现这一点: def reason_to_follow_Up m

假设我有这样一个数据帧:

ID糖果包装错误 0 001无1无 10021无 2 003 1 1 040 3 004无1 040 4 005 11无 我想要一个这样的新专栏:

要跟进的ID Candy包装器错误原因 0 001无1无未制造的匹配糖果。 1 002 1无匹配包装未制造。 2 003 1 1040工厂故障。 3 004无1 040工厂故障。 4 005 11无 我一直使用np.vectorize来实现这一点:

def reason_to_follow_Up manufacture_candy,manufacture_wrapper,错误: 味精=[] def candy_非_制造商制造_糖果,制造_包装,错误: 如果不生产糖果: 如果生产包装纸: 如果没有错误: 味精。未生产糖果。 def包装纸\u未\u生产制造\u糖果,制造\u包装纸,错误: 如果不生产包装纸: 如果制造糖果: 如果没有错误: msg.appendMatching包装未制造。 def特定_错误错误: 如果出现错误: 如果错误为40: 味精。工厂故障。 糖果\u非\u制造商制造\u糖果,制造商\u包装,错误 包装纸\u未\u制造糖果,制造\u包装纸,错误 特定错误 如果不是味精: 一无所获 其他: 返回“,”。joinmsg df['Reason to Follow']=np.vectorizereason_to_Follow_updf['Candy'], df['Wrapper'], df['Error'] 我喜欢这个有几个原因:

我喜欢将所有逻辑封装到一个用户定义的函数中,然后运行该函数。我发现我可以详细地注释我的函数,它更模块化,它有点像我的队友熟悉的Excel中的公式生成器,等等。另外,我不熟悉很多内置函数,发现很难找到它们,例如df。将提出许多自动完成的建议

矢量化看起来非常干净

有没有办法在for循环中应用我的用户定义函数,而不必在顶部导入numpy

或者是熊猫。申请还是。地图

完整代码示例:

作为pd进口熊猫 将numpy作为np导入 数据={'ID':['001'、'002'、'003'、'004'、'005'], “糖果”:[None,1,1,None,1], “包装器”:[1,无,1,1,1], 'Error':[None,None,040,040,None]} df=pd.DataFramedata,dtype=str def reason_to_follow_Up manufacture_candy,manufacture_wrapper,错误: 味精=[] def candy_非_制造商制造_糖果,制造_包装,错误: 如果不生产糖果: 如果生产包装纸: 如果没有错误: 味精。未生产糖果。 def包装纸\u未\u生产制造\u糖果,制造\u包装纸,错误: 如果不生产包装纸: 如果制造糖果: 如果没有错误: msg.appendMatching包装未制造。 def特定_错误错误: 如果出现错误: 如果错误为40: 味精。工厂故障。 糖果\u非\u制造商制造\u糖果,制造商\u包装,错误 包装纸\u未\u制造糖果,制造\u包装纸,错误 特定错误 如果不是味精: 一无所获 其他: 返回“,”。joinmsg df['Reason to Follow']=np.vectorizereason_to_Follow_updf['Candy'], df['Wrapper'], df['Error']
我怀疑你能用熊猫地图;但是,可以使用numpy select使其更简单:


所以,我知道列表生成器,但没有意识到我实际上可以压缩多个列,因此可以使用每个列的值:

df['Reason to Follow']=[Reason_to_Follow_upmanufacture_candy,manufacture_wrapper,error 用于制作糖果,制作包装,错误 在zipdf['Candy'],df['Wrapper'],df['Error']] 这起作用了

我用np.vectorize来计时,通常速度是np.vectorize的两倍

然而,我仍然认为我应该使用np.vectorize,因为它仍然更干净,而且我的代码中的瓶颈通常是数据可视化,而不是操作部分

 data = {'ID': ['001','002','003', '004', '005'],
        'Candy': [None, 1, 1, None, 1],
        'Wrapper': [1, None, 1, 1, 1],
        'Error': [None, None, "040", "040", None]}

 df = pd.DataFrame(data, dtype=str)



cond_candy=    df['Candy'].isnull() & df['Wrapper'].notnull() & 
               df['Error'].isnull()

cond_wrapper=  df['Candy'].notnull() & df['Wrapper'].isnull() & 
               df['Error'].isnull()

cond_error=    df['Error'].isin(['040'])

cond_else=     df['Candy'].notnull() & df['Wrapper'].notnull() & 
               df['Error'].isnull()

condlist =   [cond_candy, cond_wrapper, cond_error, cond_else]
choicelist = ["Matching candy not manufactured.",
              "Matching wrapper not manufactured.",
              "Factory malfunction.",
              None
              ]

df['reason'] = np.select(condlist,choicelist)

df


    ID      Candy   Wrapper     Error      reason
0   001     None        1       None    Matching candy not manufactured.
1   002     1         None      None    Matching wrapper not manufactured.
2   003     1           1       040     Factory malfunction.
3   004     None        1       040     Factory malfunction.
4   005     1           1       None    None