Как развернуть ряд кортежей в pandas DataFrame в несколько строк в качестве мультииндекса? - PullRequest
1 голос
/ 09 апреля 2020

Пример DataFrame:

>>> idx = pd.MultiIndex.from_arrays([['foo', 'foo', 'bar', 'bar'], ['one', 'two', 'one', 'two']])
>>> df = pd.DataFrame({'Col1': [('a', 'b'), 'c', 'd', 'e'], 'Col2': [('A', 'B'), 'C', 'D', 'E']}, index=index)
>>> print(df)
           Col1    Col2
foo one  (a, b)  (A, B)
    two       c       C
bar one       d       D
    two       e       E

Я хочу преобразовать DataFrame, распаковав ряд кортежей, сохранив все под своим первоначальным индексом, в результате чего получится что-то вроде этого:

          Col1 Col2
foo one 0    a    A
        1    b    B
    two 0    c    C
bar one 0    d    D
    two 0    e    E

Я могу просто распаковать кортежи, но у меня просто не получается понять, как заново вставить новые строки в DataFrame. Это пример того, что я уже пробовал:

>>> unpacked = pd.DataFrame(df.loc['foo', 'one'].tolist(), index=df.columns).T
>>> print(unpacked)
  Col1 Col2
0    a    A
1    b    B
>>> df.loc['foo', 'one'] = unpacked
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "C:\Program Files\Python37\lib\site-packages\pandas\core\indexing.py", line 190, in __setitem__
    self._setitem_with_indexer(indexer, value)
  File "C:\Program Files\Python37\lib\site-packages\pandas\core\indexing.py", line 645, in _setitem_with_indexer
    value = self._align_frame(indexer, value)
  File "C:\Program Files\Python37\lib\site-packages\pandas\core\indexing.py", line 860, in _align_frame
    raise ValueError('Incompatible indexer with DataFrame')
ValueError: Incompatible indexer with DataFrame

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

1 Ответ

1 голос
/ 09 апреля 2020

Используйте Series.explode в понимании списка с помощью concat, а затем добавьте новый уровень на GroupBy.cumcount:

df = pd.concat([df[x].explode() for x in df.columns], axis=1)
df = df.set_index(df.groupby(df.index).cumcount(), append=True)
print (df)
          Col1 Col2
foo one 0    a    A
        1    b    B
    two 0    c    C
bar one 0    d    D
    two 0    e    E
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...