Есть ли способ добавить дубликаты строк в DataFrame с правой стороны как новые столбцы? - PullRequest
1 голос
/ 03 марта 2020

У меня есть набор данных, который содержит строки с дубликатами в одном столбце, но разные значения в других столбцах. Мне нужно объединить эти повторяющиеся строки, сохраняя значения из каждой строки. Ниже приведен пример с дублирующимися значениями в столбце «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

Что мне нужно, так это строки с дублирующимся идентификатором, перемещенные вправо с новыми столбцами (возможно, с некоторым префиксом, чтобы обеспечить уникальность имен столбцов) , Требуемый вывод:

        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 и добавить к исходному кадру data. Однако этот метод очень медленный, и ему было интересно, есть ли более простой способ добиться этого.

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 столбцов с примерно 10 дубликатами для каждого идентификатора. , поэтому я ищу метод, который быстрее, чем выше.

Ответы [ 3 ]

1 голос
/ 03 марта 2020

Самостоятельное объединение будет работать хорошо, ответьте ниже и в этом вопросе: самостоятельное объединение с Pandas

df.join(df.drop('ID', 1), on='ID', rsuffix='1')
0 голосов
/ 03 марта 2020

Другой способ использования 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
0 голосов
/ 03 марта 2020

Это решает ваш запрос; вам нужно будет проверить его и посмотреть, масштабируется ли он

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»

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...