#pandas #dataframe #classification
Вопрос:
У меня есть набор данных, содержащий 30 столбцов. Последний столбец является целевой переменной в классификации.
Мне нужно случайным образом удалить 10% значений атрибутов. Таким образом, 10% значений из столбцов 0-29 должны быть NA. Я также хочу, чтобы удаление данных происходило случайным образом, т. Е. Я не хочу, чтобы все столбцы имели одинаковый процент удаления. Я требую, чтобы все столбцы имели разный процент удаления. Но в целом все столбцы, взятые вместе, должны составлять 10%, удаленных от исходных значений атрибутов.
Помощь была бы очень признательна.
Ответ №1:
Что-то подобное может быть тем, что вы ищете.
import numpy as np
# get dimensions of df
nrows, ncols = len(df.index), 30
volume = nrows * ncols # total number of entries in df
volume_to_be_nan = int(volume * 0.1) # number of entries to turn to NaN (10 %)
# randomly generate index locations for the new NaNs
indices = np.random.randint(volume, size=volume_to_be_nan)
row_indices = indices % nrows
col_indices = (indices / nrows).astype(int)
# assign NaN to each of the indices in df
for ri, ci in zip(row_indices, col_indices):
df.iloc[ri, ci] = np.nan
Например, если df
это:
0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29
0 19 52 65 85 76 79 99 85 53 20 35 2 66 58 51 56 63 46 0 63 14 27 79 45 30 83 35 32 45 16
1 37 16 75 28 23 77 19 99 34 70 31 74 59 85 90 83 85 2 16 12 6 18 2 16 42 95 54 4 57 23
2 54 54 99 96 64 43 65 17 72 82 19 26 10 64 82 18 72 53 49 76 90 29 6 40 80 57 48 60 75 17
3 57 33 82 28 14 29 2 69 4 67 23 87 31 34 12 86 74 67 32 69 43 19 63 6 78 31 12 16 60 60
4 10 82 26 62 22 21 37 17 33 20 40 93 50 75 24 91 41 79 56 24 5 89 95 59 80 36 23 38 41 79
Затем приведенный выше код возвращается df
, чтобы быть:
0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29
0 NaN 52.0 65 85.0 76 79.0 99 85 53.0 20 35 2 NaN 58.0 51.0 56.0 63 46 0.0 63 14 27 79 45 30.0 83 35 32 NaN 16
1 37.0 NaN 75 28.0 23 77.0 19 99 34.0 70 31 74 59.0 NaN NaN NaN 85 2 16.0 12 6 18 2 16 42.0 95 54 4 57.0 23
2 54.0 54.0 99 96.0 64 NaN 65 17 72.0 82 19 26 10.0 64.0 82.0 18.0 72 53 NaN 76 90 29 6 40 80.0 57 48 60 NaN 17
3 57.0 33.0 82 28.0 14 NaN 2 69 NaN 67 23 87 NaN 34.0 12.0 86.0 74 67 32.0 69 43 19 63 6 NaN 31 12 16 60.0 60
4 10.0 82.0 26 NaN 22 21.0 37 17 33.0 20 40 93 50.0 75.0 24.0 91.0 41 79 56.0 24 5 89 95 59 80.0 36 23 38 41.0 79
Здесь общее количество записей равно 150, а общее количество NAN, распределенных случайным образом по кадру данных, равно 15 (что составляет 10% от 150).
Ответ №2:
Конечно, решение Джейдена работает, но вы можете получить желаемый результат без сложного программирования, используя функции pandas. В основном вам нужно переплавить() все столбцы в один столбец; затем случайным образом выбрать нужное количество строк; и, наконец, повернуть() к исходной форме фрейма данных. Хорошо проверить количество nan в конце, чтобы убедиться, что все работает так, как предполагалось.
import numpy as np
import pandas as pd
df = pd.DataFrame(np.random.randint(1,99,size=(4, 30)),columns=list(range(0,30)))
df = df.reset_index()
df_onecolumn = pd.melt(df, id_vars=['index'])
df_sampled = df_onecolumn.sample(frac=0.9).reset_index(drop=True)
df_fraction = df_sampled.pivot(index='index', columns='variable', values='value')
df_fraction.isna().sum().sum()