Как разделить данные столбца и создать новый DataFrame с несколькими столбцами - PullRequest
0 голосов
/ 02 июля 2018

Я хотел бы разделить данные в следующем фрейме данных

df = pd.DataFrame(data={'per': np.repeat([10,20,30], 32), 'r':12*range(8), 'cnt': np.random.randint(300, 400, 96)}); df

    cnt  per  r
0   355   10  0
1   359   10  1
2   347   10  2
3   390   10  3
4   304   10  4
5   306   10  5
..  ...  ... ..
87  357   30  7
88  371   30  0
89  396   30  1
90  357   30  2
91  353   30  3
92  306   30  4
93  301   30  5
94  329   30  6
95  312   30  7

[96 rows x 3 columns]

так, что для каждого значения r в DataFrame существует новый столбец cnt_r{r}, но также сохраняется соответствующий столбец per.

Следующий фрагмент кода почти выполняет то, что я хочу, за исключением того, что он теряет столбец per:

pd.DataFrame({'cnt_r{}'.format(i): df[df.r==i].reset_index()['cnt'] for i in range(8)})

   cnt_r0  cnt_r1  cnt_r2  cnt_r3  cnt_r4  cnt_r5  cnt_r6  cnt_r7
0     355     359     347     390     304     306     366     310
1     394     331     384     312     380     350     318     396
2     340     336     360     389     352     370     353     319
...
9      341     300     386     334     386     314     358     326
10     357     386     311     382     356     339     375     357
11     371     396     357     353     306     301     329     312

Мне нужен способ построить следующий DataFrame:

   per  cnt_r0  cnt_r1  cnt_r2  cnt_r3  cnt_r4  cnt_r5  cnt_r6  cnt_r7
0   10     355     359     347     390     304     306     366     310
1   10     394     331     384     312     380     350     318     396
2   10     340     336     360     389     352     370     353     319
...
7   20     384     385     376     323     345     339     339     347
9   30     341     300     386     334     386     314     358     326
10  30     357     386     311     382     356     339     375     357
11  30     371     396     357     353     306     301     329     312

Обратите внимание, что по построению мой набор данных имеет одинаковое количество значений на per для каждого r. Очевидно, мой набор данных намного больше, чем пример (около 800 миллионов записей).

Большое спасибо за ваше время.

1 Ответ

0 голосов
/ 02 июля 2018

Если возможно, используйте reshape для 2d array, а затем insert новый столбец per:

np.random.seed(1256)

df = pd.DataFrame(data={'per': np.repeat([10,20,30], 32), 
                        'r': 12*list(range(8)), 
                        'cnt': np.random.randint(300, 400, 96)})


df1 = pd.DataFrame(df['cnt'].values.reshape(-1, 8)).add_prefix('cnt_r')
df1.insert(0, 'per', np.repeat([10,20,30], 4))
print (df1)
    per  cnt_r0  cnt_r1  cnt_r2  cnt_r3  cnt_r4  cnt_r5  cnt_r6  cnt_r7
0    10     365     358     305     311     393     343     340     313
1    10     393     319     358     351     322     387     316     359
2    10     360     301     337     333     322     337     393     396
3    10     320     344     325     310     338     381     314     339
4    20     323     305     342     340     343     319     332     371
5    20     398     308     350     320     340     319     305     369
6    20     344     340     345     332     373     334     304     331
7    20     323     349     301     334     344     374     300     336
8    30     357     375     396     354     309     391     304     334
9    30     311     395     372     359     370     342     351     330
10   30     378     302     306     341     308     392     387     332
11   30     350     373     316     376     338     351     398     304

Или используйте cumcount для создания новых групп и изменения формы на set_index с unstack:

df = (df.set_index([df.groupby('r').cumcount(), 'per','r'])['cnt']
        .unstack()
        .add_prefix('cnt_r')
        .reset_index(level=1)
        .rename_axis(None, axis=1))
print (df)
    per  cnt_r0  cnt_r1  cnt_r2  cnt_r3  cnt_r4  cnt_r5  cnt_r6  cnt_r7
0    10     365     358     305     311     393     343     340     313
1    10     393     319     358     351     322     387     316     359
2    10     360     301     337     333     322     337     393     396
3    10     320     344     325     310     338     381     314     339
4    20     323     305     342     340     343     319     332     371
5    20     398     308     350     320     340     319     305     369
6    20     344     340     345     332     373     334     304     331
7    20     323     349     301     334     344     374     300     336
8    30     357     375     396     354     309     391     304     334
9    30     311     395     372     359     370     342     351     330
10   30     378     302     306     341     308     392     387     332
11   30     350     373     316     376     338     351     398     304
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...