2017-07-18 77 views
1

我是熊猫和Numpy的新手。我有一个数据框,我希望通过对列的每一行应用一个函数来创建一个新列。我们来看一个简化的例子:如果第一个功能失败,请使用第二个功能

import pandas as pd 
import numpy as np 

df = pd.DataFrame(columns=["names"], data=["Brussels", 2, "New York"]) 

def to_lower(value): 
    try: 
     return value.lower() 
    except AttributeError: 
     return None 

def to_string(value): 
    return str(value) 

df['lower_names'] = np.vectorize(to_lower)(df['names']) 

该操作工作得很好。现在我想将to_string()to_lower()仅应用于结果为None的“lower_names”的行(我不知道这是否非常清楚)。

这看起来很基本,但我有麻烦。我可以详细描述我的尝试,但是我害怕出现一个白痴......也许我应该在一周或两周之前学习这两个模块,但在此之前,任何建议都会受到欢迎。

编辑:@jezrael解决方案是正确的......对于我的简化示例。现在让我们想象一下,我想仅在列名“行”的行中应用np.vectorize(to_string)函数,然后np.vectorize(to_lower),其中第一个结果为None,那么执行该操作的最佳方式是什么?

回答

2

我认为你需要改变return Nonereturn to_string(value)

def to_lower(value): 
    try: 
     return value.lower() 
    except AttributeError: 
     return to_string(value) 

def to_string(value): 
    return str(value) 

df['lower_names'] = np.vectorize(to_lower)(df['names']) 


print (df['lower_names'].apply(type)) 
0 <class 'str'> 
1 <class 'str'> 
2 <class 'str'> 
Name: lower_names, dtype: object 

也有可能使用astype的转换和所有值str然后str.lower

df['lower_names'] = df['names'].astype(str).str.lower() 
+0

谢谢@jezrael,这是部分我的尝试。它在我简化的例子中运行得非常好,但不在我的实际数据中,我不知道为什么......同时,简化问题并将其发布在SO上,可以帮助我清楚地了解自己的反思。 –

+1

@EttoreRizza - 我相信如此。尝试一些调试或尝试解释更多什么是问题。 – jezrael

+0

你是对的,当然,我通过简化它提出了一个错误的问题。我会编辑它,如果没有其他人更准确地回答我错误定义的问题,请接受您的回答。 –