有没有一种方法可以将DataFrame中的重复行作为新列追加到右侧?

时间:2020-03-03 06:02:27

标签: python pandas dataframe

我有一个数据集,其中包含一列中具有重复项的行,而另一列中具有不同的值。我需要合并这些重复的行,同时保留每行的值。请参见下面的示例,其中“ ID”列中的值重复。

data={'ID':['01.560','05.890','05.890','02.564'],'Foo':[1,4,7,6],'Ba':['cat','dog','rabbit','monkey'],'Bar':[5.76,9.99,1.20,7.19]}
df=pd.DataFrame(data)


output:
       ID  Foo      Ba   Bar
0  01.560    1     cat  5.76
1  05.890    4     dog  9.99
2  05.890    7  rabbit  1.20
3  02.564    6  monkey  7.19

我需要的是将具有重复ID的行移动到带有新列的右侧(可能带有一些前缀以确保col名称是唯一的)。所需的输出是:

        Foo      Ba   Bar  Foo1  Ba1  Bar1
ID                       
01.560    1     cat  5.76  NaN   NaN   NaN
05.890    4     dog  9.99  7  rabbit  1.20
02.564    6  monkey  7.19  NaN   NaN   NaN

我尝试将重复的行添加到dict,然后从该dict生成一个新的数据框,然后附加到原始数据框。但是,此方法非常慢,并且想知道是否有更简单的方法来实现此目的。

def singl_line(ID,df):    
    line_num = 1
    results=dict()
    for i in range(len(df.loc[df['ID'] == ID])):
        fll=df.to_dict('records')[df.loc[df['ID'] == ID].index[i]]
        numbered=dict(("{} {}".format(k,line_num),v) for k,v in fll.items())
        line_num+=1
        results.update(numbered)
        continue
    return results
df_1ln=pd.DataFrame()
full=df['ID'].tolist()
nodup = [] 
for i in full: 
    if i not in nodup: 
        nodup.append(i)
    continue
nodup

for i in nodup:
    temp=pd.DataFrame([singl_line(i,df)],columns=singl_line(i,df).keys())
    df_1ln=df_1ln.append(temp,sort=False)
    continue
df_1ln

output:
     ID 1  Foo 1    Ba 1  Bar 1    ID 2  Foo 2    Ba 2  Bar 2
0  01.560      1     cat   5.76     NaN    NaN     NaN    NaN
0  05.890      4     dog   9.99  05.890    7.0  rabbit    1.2
0  02.564      6  monkey   7.19     NaN    NaN     NaN    NaN

我正在使用的数据集具有〜4000行和150列,每个ID大约有10个重复项,因此我正在寻找一种比上述方法更快的方法。

3 个答案:

答案 0 :(得分:1)

自我连接会很好地工作,请在下面和以下问题中回答: self-join with Pandas

df.join(df.drop('ID', 1), on='ID', rsuffix='1')

答案 1 :(得分:0)

这解决了您的请求;您将不得不对其进行测试,看看它是否可扩展

M = df.loc[df.duplicated('ID')].add_suffix('_1').set_index('ID_1')

orig = df.drop_duplicates('ID').set_index('ID')

pd.concat([orig,M],axis=1)

        Foo Ba       Bar    Foo_1   Ba_1    Bar_1
 01.560 1   cat     5.76    NaN     NaN     NaN
 05.890 4   dog     9.99    7.0     rabbit  1.2
 02.564 6   monkey  7.19    NaN     NaN     NaN

在列轴上获取具有重复值的数据框,并与具有重复自由值的数据框连接。请注意,索引设置为“ ID”

答案 2 :(得分:0)

使用pivot的另一种方法(不过,您将不得不重新组织列):

result = (df.assign(count=df.groupby("ID").cumcount())
            .pivot(index='ID', columns='count'))

result.columns = ["_".join(str(x) for x in i) for i in result.columns]

print (result)

        Foo_0  Foo_1    Ba_0    Ba_1  Bar_0  Bar_1
ID                                                
01.560    1.0    NaN     cat     NaN   5.76    NaN
02.564    6.0    NaN  monkey     NaN   7.19    NaN
05.890    4.0    7.0     dog  rabbit   9.99    1.2