2017-09-28 50 views
1

此处的总崩溃需要一些帮助。熊猫在单独的列中合并具有ID的行

我有+10米行的数据帧和一些150列与两个ID,恰似下面:

df = pd.DataFrame({'id1' : [1,2,5,3,6,4] 
       ,'id2' : [2,1,np.nan,4,np.nan,3] 
       ,'num' : [123, 3231, 123, 231, 6534,2394]}) 


    id1 id2 num 
0 1 2.0 123 
1 2 1.0 3231 
2 5 NaN 123 
3 3 4.0 231 
4 6 NaN 6534 
5 4 3.0 2394 

凡行索引0和1是在一对给定的ID1和ID2,和行索引3和5是一对一样的。我想下面的表格,其中第二行对被合并第一行对

df = pd.DataFrame({'id1' : [1,5,3,6] 
       ,'id2' : [2,np.nan,3,np.nan] 
       ,'num' : [123, 123, 231, 6534] 
       ,'2num' : [3231, np.nan, 2394, np.nan,]}) 


    id1 id2 num 2_num 
0 1 2.0 123 3231.0 
1 5 NaN 123 NaN 
2 3 3.0 231 2394.0 
3 6 NaN 6534 NaN 

怎么可以这样使用ID1和ID2和标签从“ID第2行”与“2_8”所有下面的列进行归档?

回答

3

继承人一个基于合并的方式,(谢谢@pirSquared改进)。即

ndf = df.merge(df, 'left', left_on=['id1', 'id2'], right_on=['id2', 'id1'], suffixes=['', '_2']).drop(['id1_2', 'id2_2'], 1) 
cols = ['id1','id2'] 
ndf[cols] = np.sort(ndf[cols],1) 
new = ndf.drop_duplicates(subset=['id1','id2'],keep='first') 
 
    id1 id2 num num_2 
0 1.0 2.0 123 3231.0 
2 5.0 NaN 123  NaN 
3 3.0 4.0 231 2394.0 
4 6.0 NaN 6534  NaN 
+1

我试试这个'df.merge(df,'left',left_on = ['id1','id2'],right_on = ['id2','id1'],suffixes = ['','_2'] ).drop(['id1_2','id2_2'],1)' – piRSquared

+0

感谢很多先生后缀是美丽的,希望我以同样的方式 – Dark

+0

我的建议不起作用,但是'suffixes' help( - : – piRSquared

2

这个想法是对每一对ID进行排序,以便我们按它们进行分组。

cols = ['id1', 'id2'] 
df[cols] = np.sort(df[cols], 1) 

df.set_index(
    cols + [df.fillna(-1).groupby(cols).cumcount() + 1] 
).num.unstack().add_suffix('_num').reset_index() 

    id1 id2 1_num 2_num 
0 1.0 2.0 123.0 3231.0 
1 3.0 4.0 231.0 2394.0 
2 5.0 NaN 123.0  NaN 
3 6.0 NaN 6534.0  NaN 
+0

这怎么可能。我挠我的头,使用合并。我成功了一半。后来想到了另一种方法,即排序。你已经把它放在这里了。 14分钟前 – Dark

+0

下一次,你会记得这一刻,速度更快。同样,我必须感谢@Psidom能够在这里快速响应( - : – piRSquared

+0

先生,我把我的基于合并的答案放在那里。除列名以外的任何可以改进的地方? – Dark

1

用途:

df[['id1','id2']] = pd.DataFrame(np.sort(df[['id1','id2']].values, axis=1)).fillna('tmp') 
print (df) 
    id1 id2 num 
0 1.0 2 123 
1 1.0 2 3231 
2 5.0 tmp 123 
3 3.0 4 231 
4 6.0 tmp 6534 
5 3.0 4 2394 

df1 = df.groupby(['id1','id2'])['num'].apply(list) 
print (df1) 
id1 id2 
1.0 2.0 [123, 3231] 
3.0 4.0 [231, 2394] 
5.0 tmp   [123] 
6.0 tmp   [6534] 
Name: num, dtype: object 

df2 = pd.DataFrame(df1.values.tolist(), 
        index=df1.index, 
        columns=['num','2_num']) 
     .reset_index().replace('tmp', np.nan) 

print (df2) 
    id1 id2 num 2_num 
0 1.0 2.0 123 3231.0 
1 3.0 4.0 231 2394.0 
2 5.0 NaN 123  NaN 
3 6.0 NaN 6534  NaN 
+0

我得到:TypeError:无法订购的类型:str )> float() – swepab

+0

然后尝试将'tmp'改为某些'int'值不在'id1','id2'如'-100'或'1000'或'-1' – jezrael

+0

对不起,错字,我的不好! – swepab