Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/haskell/8.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 有没有办法将DataFrame中的重复行作为新列附加到右侧?_Python_Pandas_Dataframe - Fatal编程技术网

Python 有没有办法将DataFrame中的重复行作为新列附加到右侧?

Python 有没有办法将DataFrame中的重复行作为新列附加到右侧?,python,pandas,dataframe,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

我有一个数据集,其中一列中包含重复的行,但其他列中包含不同的值。我需要合并这些重复的行,同时保留每行的值。请参见下面的示例,其中“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的行与新列一起向右移动(可能带有一些前缀以确保列名称是唯一的)。所需输出为:

        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个副本,因此我正在寻找一种比上面的方法更快的方法。

这解决了您的请求;你必须测试它,看看它是否可扩展

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”

另一种方法是使用
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
df.join(df.drop('ID', 1), on='ID', rsuffix='1')