pandas dataframe基于标签添加新列

时间:2014-07-02 07:28:28

标签: python numpy pandas

假设我有一个这样的数据框:

name   gender
John    1
Alice   0
Michael 1

我有另一个名为Port的数据点,表明这些人的出发点。端口具有不同的值(例如,1,2 3)。假设John开始使用端口1,Alice安装在2端,迈克尔则在3端。

如何使用pandas获取下表:

name  gender  port1   port2   port3
John    1       1       0       0
Alice   0       0       1       0
Michael 1       0       0       1

修改 我现在这样做的方式是每个标签半手动。

port_dict = {'port1': 0, 'port2': 1, 'port3': 2}
for port, num in port_dict.items():    
    train_df[port] = train_df.Embarked[train_df.Embarked==num]
    train_df[port].fillna(0, inplace=True)

但是这给了我在端口{1,2,3}列中的所有0。

EDIT2 实际上,上述解决方案有效。但是有更好的方法吗?

2 个答案:

答案 0 :(得分:1)

不确定Embarkedtrain_df属性的来源。 这是我解决问题的方法,不知道它是否可以被描述为更好的方式。

import pandas as pd

df = pd.DataFrame({'name': ['John', 'Alice', 'Michael'], 
              'gender': [1, 0, 1], 'port_num': [1, 2, 3] })

for i in set(df.port_num.values):    
    df['port{0}'.format(i)] = (df.port_num == i).astype(int)

这显然不适用于名称比port1更有意义的端口,您需要port_num列作为端口名称字符串,或者像中那样构建字典修改

答案 1 :(得分:0)

我使用以下一组功能:

def discrim(row, catField, cat, srcField):
    if srcField in row:
        if row[catField]==cat:
            return row[srcField]
        else:
            pass
    else:
        if row[catField]==cat:
            return srcField
    return 0

def CatToAtt(data, source, catField):
    clist = list(data[catField].unique())
    for a in clist:
        data['_att_' + str(a)] = data.apply(lambda x: discrim(x,catField, a, source), axis=1)
    return clist

def getAtts(data):
    alist = []
    for a in data.columns:
        if "_att_" in a:
            alist.append ( a)
    return alist

使用CatToAtt将包含分类数据的字段转换为一组包含二进制{1,0}的字段,以识别该行是否属于特定类别类型。它对于为随机森林或其他统计/机器学习过程准备数据非常有用。

例如,假设我有一个名为" Port"其中包含来自["伦敦","南安普顿","瑟堡","皇后镇"]的值,名为泰坦尼克号。我可以运行以下内容:

CatToAtt(titanic, 1, "Port")

这会将以下列添加到泰坦尼克数据框

["_att_London", "_att_Southampton", "_att_Cherbourg", "_att_Queenstown"]

如果与" Port"匹配,则每个填充1;列和相应的类别值,如果不是,则为0。

如果稍后,您希望快速获取以这种方式创建的所有列的列表,只需调用getAtts以返回列表(它假定没有人将使用" att "这里使用的命名约定 - 相当安全,但如果遇到一些例外情况可以编辑)

您可能尝试的替代方案可能是:

def CatToAttAlternative(data, source, catField):
    clist = list(data[catField].unique())
    for a in clist:
        data[str(catField) + str(a)] = data.apply(lambda x: discrim(x, catField, a, source), axis=1)
    return clist

有效地做同样的事情,只是使用命名约定,使用source-column-name作为前缀而不是" att "如果应用于您的示例,则应返回与您的示例更匹配的结果(即{Port1,Port2,Port3}之一等)

希望有所帮助,如果我能进一步解释,请告诉我。