2014-11-06 2 views
2

У меня есть фрейм данных, который содержит несколько идентификаторов. Я хочу создать один новый «идентификатор группы» для каждой уникальной комбинации идентификаторов. Позже я хочу запустить регрессии с помощью statsmodels. То есть, скажем, у меня естьСоздать идентификаторы групп для регрессий

id1 id2 id3 
    A 1 100 
    A 1 101 
    B 1 100 
    B 1 100 

Я хочу, чтобы получить

id1 id2 id3 groupid 
    A 1 100  0 
    A 1 101  1 
    B 1 100  2 
    B 1 100  2 

с id1, id2, id3 как набор идентификаторов. Я знаю, что могу получить unique(), чтобы получить уникальные группы, но как бы я мог эффективно кодировать строки, в какие из уникальных групп они принадлежат?

Скорректированная @ ответ Берни, чтобы приспособить для потенциальных «Нэн:

# get a DataFrame with just the unique "keys" 
df2 = df.replace(np.NaN, -1) 
g = df2.groupby([u'id1',u'id2',u'id3']) 
gdf = pd.DataFrame(g.groups.keys(),columns=df.columns) 
gdf = gdf.replace(-1, np.NaN) 
# an idea is to re-use the index as the 'group_id' 
# the next three commands support that 
gdf.sort([u'id1',u'id2',u'id3'],inplace=True) 
gdf.reset_index(drop=True,inplace=True) 
gdf['group_id'] = gdf.index 

# merge on the three id columns 
mdf = df.merge(gdf,how='inner',on=df.columns.tolist()) 

ответ

1

Конечно Есть множество решений. Это было то, что я прибыл в ...

>>> df 
    id1 id2 id3 
0 A 1 100 
1 A 1 101 
2 B 1 100 
3 B 1 100 

# get a DataFrame with just the unique "keys" 
g = df.groupby([u'id1',u'id2',u'id3']) 
gdf = pd.DataFrame(g.groups.keys(),columns=df.columns) 

# an idea is to re-use the index as the 'group_id' 
# the next three commands support that 
gdf.sort([u'id1',u'id2',u'id3'],inplace=True) 
gdf.reset_index(drop=True,inplace=True) 
gdf['group_id'] = gdf.index 

# merge on the three id columns 
mdf = df.merge(gdf,how='inner',on=df.columns.tolist()) 

Производит:

 
    id1 id2 id3 group_id 
0 A 1 100   0 
1 A 1 101   1 
2 B 1 100   2 
3 B 1 100   2 
+0

Я предпочитаю этот ответ, потому что я могу передать список столбцов - тоже, я бы ожидать, что это будет более эффективным , – FooBar

+1

Вы должны заменить первую строку следующим: 'df2 = df.replace (np.NaN, -1)', 'g = df2.groupby (...)'. «groupby» не работает («как ожидается здесь») с «NaN» и создаст отдельную группу для каждого значения «NaN». – FooBar

+0

Спасибо, @FooBar. Я обновил ответ. Сбрасывает ли NaN смысл для ваших целей? – bernie

1

Это то, что вы ищете?

df = pd.DataFrame({'id1': ['A','A','B','B'],'id2':[1,1,1,1],'id3':[100,101,100,100]}) 

def makegroup(x,y,z): 
    return str(x) + str(y) + str(z) 

df['groupid'] = df.apply(lambda row: makegroup(row['id1'], row['id2'], row['id3']), axis=1) 

groupiddict = {} 
groupincrimenter = 1 

for x in df['groupid'].unique(): 
    groupiddict[x] = groupincrimenter 
    groupincrimenter += 1 

df['groupidINT'] = df.apply(lambda row: int(groupiddict[row['groupid']]), axis=1) 

Вот выход:

id1 id2 id3 groupid groupidINT 
0 A 1 100 A1100   1 
1 A 1 101 A1101   2 
2 B 1 100 B1100   3 
3 B 1 100 B1100   3 
Смежные вопросы