У меня есть набор данных, похожий на df1 здесь

    df1 = pd.DataFrame({'id':[1,1,2,2,2],
                      'value':[67,45,7,5,9]})

   id  value
   1     67
   1     45
   2      7
   2      5
   2      9

Я хочу привести это к этой форме. все значения, соответствующие этому идентификатору в одной ячейке, разделены пробелами.

   id values
   1  67 45
   2  7 5 9

Вот мой код

df2 = pd.DataFrame(df1['id'].unique())
df2.columns=['id']
df2['values']=np.nan

for i in df2['id']:
    s=''
    for k in df1[df1['id']==i]['value']:
        s=s+' '+str(k)
    df2.loc[df2['id']==i,'values']=s.lstrip()
print(df2)

Есть ли более питонический способ сделать это. У меня 70000 уникальных идентификаторов, каждый идентификатор может иметь количество значений в диапазоне от 1 до 20

Я использую Anaconda python 3.5 pandas 0.20.1 numpy 1.12.1 windows 10

Кроме того, как мы можем повторить то же самое в R

4
Gowtham M 28 Май 2017 в 02:34

2 ответа

Лучший ответ

Преобразуйте столбец 'value' из int в строку, затем выполните groupby для 'id' и apply str.join функция:

# Convert 'value' column to string.
df1['value'] = df1['value'].astype(str)

# Perform a groupby and apply a string join.
df1 = df1.groupby('id')['value'].apply(' '.join).reset_index()

Полученный результат:

   id  value
0   1  67 45
1   2  7 5 9
2
root 27 Май 2017 в 23:46

Вот как это сделать в R. Это тот же подход

df = data.frame('id'=c(1,1,2,2,2),'value'=c(67,45,7,5,9))
aggregate(cbind(values=value)~id,
           data = df, 
           FUN = function(x){paste(x,collapse=' ')})
0
Gowtham M 28 Май 2017 в 23:52