簡體   English   中英

熊貓數據框基於標簽添加新列

[英]pandas dataframe adding new columns based on labels

假設我有一個像這樣的數據框:

name   gender
John    1
Alice   0
Michael 1

我還有一個稱為端口的數據點,它指示了這些人的出發地。 端口具有不同的值(例如1,2 3)。 假設John登上1號港口,Alice登上2號港口,Michael登上3號港口。

如何使用熊貓獲取下表:

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)

但這使我在port {1,2,3}列中全為0。

EDIT2實際上,以上解決方案有效。 但是有更好的方法嗎?

不確定Embarked上的Embarked屬性來自train_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列作為端口名稱字符串,要么像在EDIT中那樣構建字典。

我使用以下功能:

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}的一組字段,這些二進制{1,0}標識該行是否屬於特定類別類型。 這對於為隨機森林或其他統計/機器學習過程准備數據很有用。

例如,假設我有一個名為“端口”的字段,該字段包含來自稱為“泰坦尼克號”的數據幀中的[“倫敦”,“南安普敦”,“瑟堡”,“皇后鎮”]的值。 我可以運行以下命令:

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}等)

希望能有所幫助,請讓我知道是否可以進一步解釋。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM