Проблема с объединением Pandas Dataframes со столбцами, которые не совпадают - PullRequest
0 голосов
/ 31 октября 2018

Я пытаюсь транспонировать и объединить два фрейма данных pandas, один из которых содержит счета, сегмент, в который они получили свой депозит, информацию о своем депозите и какой день они получили депозит; у другого есть счета и информация о снятии. Проблема заключается в том, что для целей индексации информация сегмента из одного кадра данных должна совпадать с информацией другого, независимо от того, происходит ли снятие или нет.

Примечания:

  • Всегда будет учетная запись для каждого человека
  • Не всегда будет вывод для каждого человека
  • Счета и данные для кадра данных снятия существуют, только если происходит снятие

Код данных учетной записи

accounts = DataFrame({'person':[1,1,1,1,1,2,2,2,2,2],
                         'segment':[1,2,3,4,5,1,2,3,4,5],
                         'date_received':[10,20,30,40,50,11,21,31,41,51],
                         'amount_received':[1,2,3,4,5,6,7,8,9,10]})

accounts = accounts.pivot_table(index=["person"], columns=["segment"])

Кадр данных аккаунта

               amount_received        date_received
segment        1  2  3  4   5         1   2   3   4   5
person
1              1  2  3  4   5        10  20  30  40  50
2              6  7  8  9  10        11  21  31  41  51

Код снятия данных с кадра

withdrawals = DataFrame({'person':[1,1,1,2,2],
                         'withdrawal_segment':[1,1,5,2,3],
                         'withdraw_date':[1,2,3,4,5],
                         'withdraw_amount':[10,20,30,40,50]})

withdrawals = withdrawals.reset_index().pivot_table(index = ['index', 'person'], columns = ['withdrawal_segment'])

Поскольку для человека могут быть только уникальные сегменты, требуется, чтобы мой столбец состоял из уникального числа только один раз, при этом сохраняя все данные, поэтому этот фрейм выглядит так сильно.

Кадр данных снятия

                      withdraw_date              withdraw_amount
withdrawal_segment    1    2    3    5           1     2     3     5
index person
0     1               1.0  NaN  NaN  NaN        10.0   NaN   NaN   NaN
1     1               2.0  NaN  NaN  NaN        20.0   NaN   NaN   NaN
2     1               NaN  NaN  NaN  3.0         NaN   NaN   NaN  30.0
3     2               NaN  4.0  NaN  NaN         NaN  40.0   NaN   NaN
4     2               NaN  NaN  5.0  NaN         NaN   NaN  50.0   NaN

Слияние

merge = accounts.merge(withdrawals, on='person', how='left')

               amount_received        date_received              withdraw_date            withdraw_amount
segment        1  2  3  4   5         1   2   3   4   5          1    2    3    5         1     2     3     5
person
1              1  2  3  4   5        10  20  30  40  50        1.0  NaN  NaN  NaN        10.0   NaN   NaN   NaN
1              1  2  3  4   5        10  20  30  40  50        2.0  NaN  NaN  NaN        20.0   NaN   NaN   NaN
1              1  2  3  4   5        10  20  30  40  50        NaN  NaN  NaN  3.0         NaN   NaN   NaN  30.0
2              6  7  8  9  10        11  21  31  41  51        NaN  4.0  NaN  NaN         NaN  40.0   NaN   NaN
2              6  7  8  9  10        11  21  31  41  51        NaN  NaN  5.0  NaN         NaN   NaN  50.0   NaN

Проблема с объединенным фреймом данных заключается в том, что сегменты из фрейма данных снятия не совпадают с сегментами счетов. Нужный кадр данных должен выглядеть примерно так:

               amount_received        date_received              withdraw_date               withdraw_amount
segment        1  2  3  4   5         1   2   3   4   5         1    2    3    4    5        1     2     3    4     5
person
1              1  2  3  4   5        10  20  30  40  50        1.0  NaN  NaN  NaN   NaN     10.0   NaN   NaN   NaN   NaN
1              1  2  3  4   5        10  20  30  40  50        2.0  NaN  NaN  NaN   NaN     20.0   NaN   NaN   NaN   NaN
1              1  2  3  4   5        10  20  30  40  50        NaN  NaN  NaN  NaN   3.0     NaN    NaN   NaN   NaN   30.0
2              6  7  8  9  10        11  21  31  41  51        NaN  4.0  NaN  NaN   NaN     NaN    40.0  NaN   NaN   NaN
2              6  7  8  9  10        11  21  31  41  51        NaN  NaN  5.0  NaN   NaN     NaN    NaN   50.0  NaN   NaN

Моя проблема в том, что я не могу объединиться между человеком и сегментами. Я думал о вставке строки и столбца, но из-за того, что я не знаю, какие сегменты есть и не будут сняты, это становится трудным. Можно ли объединить кадры данных так, чтобы они выстраивались между людьми и сегментами? Спасибо!

1 Ответ

0 голосов
/ 31 октября 2018

Метод 1, с использованием reindex

withdrawals=withdrawals.reindex(pd.MultiIndex.from_product([withdrawals.columns.levels[0],accounts.columns.levels[1]]),axis=1)
merge = accounts.merge(withdrawals, on='person', how='left')
merge
Out[79]: 
        amount_received              date_received                  \
segment               1  2  3  4   5             1   2   3   4   5   
person                                                               
1                     1  2  3  4   5            10  20  30  40  50   
1                     1  2  3  4   5            10  20  30  40  50   
1                     1  2  3  4   5            10  20  30  40  50   
2                     6  7  8  9  10            11  21  31  41  51   
2                     6  7  8  9  10            11  21  31  41  51   
        withdraw_amount                       withdraw_date                     
segment               1     2     3   4     5             1    2    3   4    5  
person                                                                          
1                  10.0   NaN   NaN NaN   NaN           1.0  NaN  NaN NaN  NaN  
1                  20.0   NaN   NaN NaN   NaN           2.0  NaN  NaN NaN  NaN  
1                   NaN   NaN   NaN NaN  30.0           NaN  NaN  NaN NaN  3.0  
2                   NaN  40.0   NaN NaN   NaN           NaN  4.0  NaN NaN  NaN  
2                   NaN   NaN  50.0 NaN   NaN           NaN  NaN  5.0 NaN  NaN 

Метод 2, с использованием unstack и stack

merge = accounts.merge(withdrawals, on='person', how='left')
merge.stack(dropna=False).unstack()
Out[82]: 
        amount_received              date_received                  \
segment               1  2  3  4   5             1   2   3   4   5   
person                                                               
1                     1  2  3  4   5            10  20  30  40  50   
1                     1  2  3  4   5            10  20  30  40  50   
1                     1  2  3  4   5            10  20  30  40  50   
2                     6  7  8  9  10            11  21  31  41  51   
2                     6  7  8  9  10            11  21  31  41  51   
        withdraw_amount                       withdraw_date                     
segment               1     2     3   4     5             1    2    3   4    5  
person                                                                          
1                  10.0   NaN   NaN NaN   NaN           1.0  NaN  NaN NaN  NaN  
1                  20.0   NaN   NaN NaN   NaN           2.0  NaN  NaN NaN  NaN  
1                   NaN   NaN   NaN NaN  30.0           NaN  NaN  NaN NaN  3.0  
2                   NaN  40.0   NaN NaN   NaN           NaN  4.0  NaN NaN  NaN  
2                   NaN   NaN  50.0 NaN   NaN           NaN  NaN  5.0 NaN  NaN  
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...