使用Python / pandas创建新的已清理字符串数据列

时间:2014-10-15 14:14:53

标签: python pandas

我有DataFrame有一些用户输入(它应该只是一个简单的电子邮件地址),以及其他一些值,如下所示:

import pandas as pd
from pandas import Series, DataFrame

df = pd.DataFrame({'input': ['Captain Jean-Luc Picard <picard@starfleet.com>','deanna.troi@starfleet.com','data@starfleet.com','William Riker <riker@starfleet.com>'],'val_1':[1.5,3.6,2.4,2.9],'val_2':[7.3,-2.5,3.4,1.5]})

由于存在错误,输入有时会包含用户名和电子邮件地址旁边的括号;这需要在继续分析之前修复。

为了继续前进,我想创建一个已清理电子邮件版本的新列:如果电子邮件包含names/brackets,则删除这些邮件,否则只需提供已正确的电子邮件。

numerous examples cleaning string data Python/pandas {}},但我尚未成功实施任何这些建议。以下是我尝试过的几个例子:

# as noted in pandas docs, turns all non-matching strings into NaN
df['cleaned'] = df['input'].str.extract('<(.*)>')

# AttributeError: type object 'str' has no attribute 'contains'
df['cleaned'] = df['input'].apply(lambda x: str.extract('<(.*)>') if str.contains('<(.*)>') else x)

# AttributeError: 'DataFrame' object has no attribute 'str'
df['cleaned'] = df[df['input'].str.contains('<(.*)>')].str.extract('<(.*)>')

谢谢!

2 个答案:

答案 0 :(得分:0)

使用np.where对包含嵌入电子邮件的行使用str.extract,对于else条件,只返回'input'值:

In [63]:

df['cleaned'] = np.where(df['input'].str.contains('<'), df['input'].str.extract('<(.*)>'), df['input'])

df

Out[63]:
                                            input  val_1  val_2  \
0  Captain Jean-Luc Picard <picard@starfleet.com>    1.5    7.3   
1                       deanna.troi@starfleet.com    3.6   -2.5   
2                              data@starfleet.com    2.4    3.4   
3             William Riker <riker@starfleet.com>    2.9    1.5   

                     cleaned  
0       picard@starfleet.com  
1  deanna.troi@starfleet.com  
2         data@starfleet.com  
3        riker@starfleet.com  

答案 1 :(得分:0)

如果你想使用正则表达式:

import re
rex = re.compile(r'<(.*)>')
def fix(s):
    m = rex.search(s)
    if m is None:
        return s
    else:
        return m.groups()[0]
fixed = df['input'].apply(fix)