#python #pandas #dataframe #combinatorics
Вопрос:
Я хочу создать два новых фрейма данных из двух существующих фреймов данных с учетом всех комбинаций их многоиндексных столбцов и их значений.
left = pd.DataFrame(([1,0,1], [1,0,0],[1,0,1],), columns=pd.MultiIndex.from_tuples([('A', 'B'), ('A', 'C' ), ('D','D'),]))
right = pd.DataFrame(([8,9], [8,9],[8,9],), columns=pd.MultiIndex.from_tuples([('S', 'T'), ('Y', 'Z'),]))
слева:
A A D
B C D
0 1 0 1
1 1 0 0
2 1 0 1
правильно:
S Y
T Z
0 8 9
1 8 9
2 8 9
ожидаемый результат
left_result:
A A A A D D
B B C C D D
0 1 1 0 0 1 1
1 1 1 0 0 0 0
2 1 1 0 0 1 1
right_result:
S Y S Y S Y
T Z T Z T Z
0 8 9 8 9 8 9
1 8 9 8 9 8 9
2 8 9 8 9 8 9
PS: Извините, если мой вопрос недостаточно точен, но пример с ожидаемым результатом по-прежнему объясняет это лучше всего без слов. Возможно, вопрос уже задавался, но в отсутствие точного описания того, какого результата я на самом деле хочу (комбинация в двух фреймах данных?), Я прошу вас помочь сформулировать вопрос более точно или связать его как дубликат, если присутствует существующий вопрос.
Ответ №1:
Мы можем использовать MultiIndex.from_product
на основе плоского индекса каждого фрейма данных, а затем reindex
на основе соответствующих значений уровня:
midx = pd.MultiIndex.from_product([left.columns.to_flat_index(),
right.columns.to_flat_index()])
left = left.reindex(columns=midx.get_level_values(0))
right = right.reindex(columns=midx.get_level_values(1))
left
:
A D
B B C C D D
0 1 1 0 0 1 1
1 1 1 0 0 0 0
2 1 1 0 0 1 1
right
:
S Y S Y S Y
T Z T Z T Z
0 8 9 8 9 8 9
1 8 9 8 9 8 9
2 8 9 8 9 8 9
midx
для справки:
MultiIndex([(('A', 'B'), ('S', 'T')),
(('A', 'B'), ('Y', 'Z')),
(('A', 'C'), ('S', 'T')),
(('A', 'C'), ('Y', 'Z')),
(('D', 'D'), ('S', 'T')),
(('D', 'D'), ('Y', 'Z'))],
)
Примечание: уровень 0 — это значения left
плоского индекса, а уровень 1 — значения right
плоского индекса.
Ответ №2:
Используйте DataFrame.reindex
Index.repeat
для столбцов ( axis=1
)
# repeat 'left' columns 2 times
>>> left = left.reindex(left.columns.repeat(2), axis=1)
>>> left
A D
B B C C D D
0 1 1 0 0 1 1
1 1 1 0 0 0 0
2 1 1 0 0 1 1
# repeat 'right' columns 3 times
>>> right = right.reindex(right.columns.repeat(3), axis=1)
>>> right
S Y
T T T Z Z Z
0 8 8 8 9 9 9
1 8 8 8 9 9 9
2 8 8 8 9 9 9
Или pandas.concat
# concatenate 'right' 3 times side by side (axis=1)
>>> right = pd.concat([right]*3, axis=1)
>>> right
S Y S Y S Y
T Z T Z T Z
0 8 9 8 9 8 9
1 8 9 8 9 8 9
2 8 9 8 9 8 9