将字符串列转换为数据框中的数字

时间:2018-04-24 08:18:03

标签: python pandas dataframe encoding

我正在尝试将DataFrame中的列转换为数字。输入是从电子邮件地址中提取的电子邮件域。样本:

>>> data['emailDomain']
0                         [gmail]
1                         [gmail]
2                         [gmail]
3                           [aol]
4                         [yahoo]
5                         [yahoo]

我想创建一个新列,如果域名为gmailaol,则列条目将为10。 我创建了一个类似这样的方法:

def convertToNumber(row):
    try:
        if row['emailDomain'] == '[gmail]':
            return 1
        elif row['emailDomain'] == '[aol]':
            return 1
        elif row['emailDomain'] == '[outlook]':
            return 1
        elif row['emailDomain'] == '[hotmail]':
            return 1
        elif row['emailDomain'] == '[yahoo]':
            return 1
        else:
            return 0
    except TypeError:
        print("TypeError")

并使用它:

data['validEmailDomain'] = data.apply(convertToNumber, axis=1)

但是,即使我知道输入列中存在gmail和aol电子邮件,我的输出列也是0。 什么可能出错?

此外,我认为条件语句的这种用法可能不是解决此问题的最有效方法。有没有其他办法来完成这项工作?

3 个答案:

答案 0 :(得分:0)

您可以通过列表推导来总结每个提供商的出现检查,并将结果列表写入data['validEmailDomain']

providers = ['gmail', 'aol', 'outlook', 'hotmail', 'yahoo']
data['validEmailDomain'] = [np.sum([p in e for p in providers]) for e in data['emailDomain'].values]

答案 1 :(得分:0)

您可以使用series.isin

providers = {'gmail', 'aol', 'yahoo','hotmail', 'outlook'}
data['emailDomain'].isin(providers)

搜索提供商

而不是对每行中的每封电子邮件应用re,您可以使用Series.str方法一次在列上执行此操作

pattern2 = '(?<=@)([^.]+)(?=\.)'
df['email'].str.extract(pattern2, expand=False)

所以这就是这样的:

pattern2 = '(?<=@)([^.]+)(?=\.)'
providers = {'gmail', 'aol', 'yahoo','hotmail', 'outlook'}
df = pd.DataFrame(data={'email': ['test.1@gmail.com', 'test.2@aol.com', 'test3@something.eu']})

provider_serie = df['email'].str.extract(pattern2, expand=False)
0        gmail
1          aol
2    something
Name: email, dtype: object
interested_providers = df['email'].str.extract(pattern2, expand=False).isin(providers)
0     True
1     True
2    False
Name: email, dtype: bool

如果您真的想要01,可以添加.astype(int)

答案 2 :(得分:0)

如果您的系列包含字符串,您的代码就可以使用。因此,它们可能包含列表,在这种情况下,您需要提取第一个元素。

我还会使用pd.Series.map而不是使用任何行方式逻辑。以下是一个完整的例子:

df = pd.DataFrame({'emailDomain': [['gmail'], ['gmail'], ['gmail'], ['aol'],
                                   ['yahoo'], ['yahoo'], ['else']]})

domains = {'gmail', 'aol', 'outlook', 'hotmail', 'yahoo'}

df['validEmailDomain'] = df['emailDomain'].map(lambda x: x[0]).isin(domains)\
                                          .astype(int)

print(df)

#   emailDomain  validEmailDomain
# 0     [gmail]                 1
# 1     [gmail]                 1
# 2     [gmail]                 1
# 3       [aol]                 1
# 4     [yahoo]                 1
# 5     [yahoo]                 1
# 6      [else]                 0