панды тасуют последние N рядов

1

Как я могу перетасовать последние N строк в кадре данных панд? Когда я говорю "перемешать", я имею в виду случайное изменение порядка строк. Это то, что я пробовал до сих пор. Я не могу понять, как правильно сбросить индекс.

import pandas as pd
import numpy as np
dat = pd.DataFrame({'d1': np.linspace(0, 1, 10)})
pd.concat([dat[:5], dat[5:].sample(frac=1).reset_index(drop=True)])

выход:

         d1
0  0.000000
1  0.111111
2  0.222222
3  0.333333
4  0.444444
0  0.777778
1  0.666667
2  0.888889
3  1.000000
4  0.555556
Теги:
pandas

3 ответа

1

Для индекса по умолчанию добавьте параметр ignore_index=True в concat:

dat = pd.DataFrame({'d1': np.linspace(0, 1, 10)})
df = pd.concat([dat[:5], dat[5:].sample(frac=1)], ignore_index=True)

Другое решение - использовать sample только для последних строк и присваивать обратно numpy array с numpy array values для предотвращения выравнивания индексов:

dat.iloc[5:] = dat.iloc[5:].sample(frac=1).values

Numpy решение с np.random.shuffle работает на месте:

np.random.shuffle(dat.iloc[5:].values)

print (df)
         d1
0  0.000000
1  0.111111
2  0.222222
3  0.333333
4  0.444444
5  0.666667
6  0.888889
7  1.000000
8  0.555556
9  0.777778
1

Нет необходимости в concat. Просто сгенерируйте случайные индексы с помощью np.random.choice и верните их на место. Вам не нужно беспокоиться об индексе таким образом.

N = 5
np.random.seed(0)

# Generate random indices. This is more efficient than shuffling data around.
idx = np.random.choice(N, N, replace=False)
# Index into a view of the data. This is also quite efficient.
v = dat['d1'].values[-N:]
dat['d1'].values[-N:] = v[idx]

print(dat)
        d1
0  0.000000
1  0.111111
2  0.222222
3  0.333333
4  0.444444
5  0.777778
6  0.555556
7  0.666667
8  0.888889
9  1.000000

Это решение может быть легко обобщено для перестановки нескольких столбцов.

idx = np.random.choice(N, N, replace=False)
v = dat.values[-N:, :]
dat.values[-N:, :] = v[idx]

print(dat)
        d1
0  0.000000
1  0.111111
2  0.222222
3  0.333333
4  0.444444
5  0.777778
6  0.555556
7  0.666667
8  0.888889
9  1.000000
0

Вы можете использовать np.permutation:

import pandas as pd
import numpy as np
dat = pd.DataFrame({'d1': np.linspace(0, 1, 10)})

print(dat)

dat.values[5:] = np.random.permutation(dat.values[5:])

print(dat)

Выход

         d1
0  0.000000
1  0.111111
2  0.222222
3  0.333333
4  0.444444
5  0.555556
6  0.888889
7  0.777778
8  1.000000
9  0.666667

Или np.random.shuffle напрямую:

np.random.seed(42)

dat = pd.DataFrame({'d1': np.linspace(0, 1, 10)})
np.random.shuffle(dat.values[5:])
print(dat)

Выход

d1
0  0.000000
1  0.111111
2  0.222222
3  0.333333
4  0.444444
5  0.666667
6  1.000000
7  0.777778
8  0.555556
9  0.888889
  • 0
    Что здесь происходит? Код работает отлично, но я озадачен этим. Почему dat.values[5:] нужно устанавливать равным чему-то новому? Всегда ли np.random.shuffle делает что-то подобное?
  • 0
    @kilojoules да шаркает делает это на месте

Ещё вопросы

Сообщество Overcoder
Наверх
Меню