Установка значений в MultiIndex DataFrame замедляется во время работы - PullRequest
1 голос
/ 21 февраля 2020

У меня есть 11729 rows × 8 columns DataFrame, я хотел бы преобразовать его в 11729 × 30 × 8 матрицу с MultiIndex, что означает 30 на каждые 30 строк 11729 строк от 0 до 11728 - 30

для более короткий пример:

исходный 2d DataFrame выглядит следующим образом:

      col0   col1
0        1      2
1        3      4
2        5      6
3        7      8
4        9     10

3d MultiIndex DataFrame, который я хочу получить, выглядит так:

           col0    col1
0    c0       1       2
     c1       3       4
     c2       5       6
1    c0       3       4
     c1       5       6
     c2       7       8
2    c0       5       6
     c1       7       8
     c2       9      10

, что означает ( 0, c0) ~ (0, c2) из ​​0 ~ 2 строк в исходном DataFrame, (1, c0) ~ (1, c2) из ​​1 ~ 3 строк в исходном DataFrame, (2, c0) ~ (2, c2) из 2 ~ 4 строк исходного DataFrame.

Я использую следующий код для преобразования исходного 2D DataFrame в MultiIndex 3D DataFrame:

multi_index = pd.MultiIndex(levels=[[],[]],
                             labels=[[],[]],
                             names=['', ''])
df = pd.DataFrame(index=multi_index, columns=origin_df.columns)
for i in range(n):
    for j in range(i, len(origin_df) - (n - i)):
        print("i{}/n{},j{}".format(i, n, j))  # print progress
        df.loc[(j, 'c%d' % i), :] = origin_df.loc[origin_df.index[j]].tolist()
for i in range(n, len(origin_df)):
    df.loc[(i, 'y'), :] = origin_df.loc[origin_df.index[i]].tolist()
return df

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

1 Ответ

1 голос
/ 21 февраля 2020

Вы не должны добавлять по одному. Вот что я бы сделал:

# toy data:
df = pd.DataFrame(np.arange(11792*8).reshape(-1,8));
window = 30
new_len = len(df) - window + 1

# create new dataframe, ignoring the index
new_df = pd.concat(df.iloc[i:i+window] for i in range(new_len))

# modify the index
new_df.index = pd.MultiIndex.from_product([np.arange(new_len), [f'c{i}' for i in range(window)]])

Это заняло около 1 секунды на 6600k. С вашими образцами данных вы получите:

      col0  col1
0 c0     1     2
  c1     3     4
  c2     5     6
1 c0     3     4
  c1     5     6
  c2     7     8
2 c0     5     6
  c1     7     8
  c2     9    10
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...