Python - Как расширить строки Pandas dataframe, чтобы включить все комбинации значений ключевых столбцов? - PullRequest
0 голосов
/ 30 августа 2018

Предположим, у меня есть следующий df:

df=pd.DataFrame({'g1':['a','b','c'],
                'g2':['x','y','z'],
                'val':[1,2,3]})
df
g1  g2  val
a   x   1
b   y   2
c   z   3       

чей «первичный ключ» (здесь используется жаргон SQL) - g1 и g2.

Как развернуть фрейм данных таким образом, чтобы в нем была строка для каждой комбинации существующих значений в g1 и g2. Для добавляемых строк лучше оставить np.nan под столбцом val. Таким образом, результат будет выглядеть следующим образом:

g1  g2  val
a   x   1.0
a   y   NaN
a   z   NaN
b   x   NaN
b   y   2.0
b   z   NaN
c   x   NaN
c   y   NaN
c   z   3.0

В настоящее время я делаю следующее, но я уверен, что это не лучшее решение:

df.set_index(['g1','g2']).T.stack().unstack().T.reset_index()

Я также могу выполнять слияния, но когда количество ключей велико, код выглядит громоздким.

Ответы [ 2 ]

0 голосов
/ 20 декабря 2018

Отвечая на мой собственный вопрос. Следующий метод должен быть намного быстрее, чем в моем вопросе, но медленнее, чем метод @ coldspeed. Это может быть хорошей альтернативой, когда типы данных уровней индекса не совпадают.

df.set_index(['g1', 'g2']).reindex(pd.MultiIndex.from_tuples(itertools.product(df.g1, df.g2)))

Грубое сравнение скорости:

  • холодная скорость: 100%
  • это: 135%
  • тот, кто в вопросе: 270%
0 голосов
/ 30 августа 2018

Используйте @ senderle's fast cartesian_product для производительности:

v = cartesian_product(df.g1, df.g2)
idx = pd.MultiIndex.from_arrays([v[:, 0], v[:, 1]])

df.set_index(['g1', 'g2']).reindex(idx)
     val
a x  1.0
  y  NaN
  z  NaN
b x  NaN
  y  2.0
  z  NaN
c x  NaN
  y  NaN
  z  3.0

%timeit df.set_index(['g1','g2']).T.stack().unstack().T
%%timeit
v = cartesian_product(df.g1, df.g2)
idx = pd.MultiIndex.from_arrays([v[:, 0], v[:, 1]])
df.set_index(['g1', 'g2']).reindex(idx)

14.6 ms ± 840 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)
4.56 ms ± 284 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...