Сделать pandas df в широкоформатном формате и объединить значения в разные столбцы - PullRequest
1 голос
/ 22 января 2020

извините, у меня возникли проблемы с объяснением проблемы в заголовке

Случайно мы повернули наш Pandas кадр данных к следующему:

df = pd.DataFrame(np.array([[1,1,2], [1,2,1], [2,1,2], [2,2,2],[3,1,3]]),columns=['id', '3s', 'score'])

id   3s  score
1    1   2
1    2   1
2    1   2             
2    2   2                 
3    1   3

Но нам нужно снять это поэтому df будет выглядеть так (оригинальная версия): столбец «3s» «разворачивается» к дискретному набору из 3 упорядоченных столбцов с 0 и 1, которые добавляются по порядку. Таким образом, если бы у нас было '3s'= 2 с 'score'= 2, значения будут [1,1,0] (2 из 3 в порядке) в столбцах ['4','5','6'] (второй набор из 3 с) для соответствующих id

df2 = pd.DataFrame(np.array([[1,1,1,0,1,0,0], [2,1,1,0,1,1,0], [3,1,1,1,np.nan,np.nan,np.nan] ]),columns=['id', '1', '2','3','4','5','6'])

id   1   2   3   4   5   6
1    1   1   0   1   0   0
2    1   1   0   1   1   0      
3    1   1   1 

Любая помощь с благодарностью! (пожалуйста, спасите меня)

Ответы [ 2 ]

2 голосов
/ 22 января 2020

Использование:

n = 3
df2 = df.reindex(index = df.index.repeat(n))
new_df = (df2.assign(score = df2['score'].gt(df2.groupby(['id','3s'])
                                                .id
                                                .cumcount())
                                         .astype(int),
                     columns = df2.groupby('id').cumcount().add(1))
             .pivot_table(index = 'id',
                          values='score',
                          columns = 'columns',
                          fill_value = '')
             .rename_axis(columns = None)
             .reset_index())
print(new_df)

Выход

   id    1    2    3  4  5  6
0   1  1.0  1.0  0.0  1  0  0
1   2  1.0  1.0  0.0  1  1  0
2   3  1.0  1.0  1.0         

Если вы хотите, вы можете использовать fill_value = 0

   id  1  2  3  4  5  6
0   1  1  1  0  1  0  0
1   2  1  1  0  1  1  0
2   3  1  1  1  0  0  0
1 голос
/ 22 января 2020

Это должно сработать:

for gr in df.groupby('3s').groups:
    for i in range(1,4):
        df[str(i+(gr-1)*3)]=np.where((df['3s'].eq(gr))&(df['score'].ge(i)), 1,0)
df=df.drop(['3s', 'score'], axis=1).groupby('id').max().reset_index()

Вывод:

   id  1  2  3  4  5  6
0   1  1  1  0  1  0  0
1   2  1  1  0  1  1  0
2   3  1  1  1  0  0  0
...