Вы можете использовать np.random.choice
для создания выборки из совокупности значений:
sample = np.random.choice(pop, size=len(df)-len(pop), replace=True)
Например,
import numpy as np
import pandas as pd
arr = np.random.randint(10, size=(10,3)).astype(float)
mask = np.random.randint(2, size=arr.shape, dtype=bool)
arr[mask] = np.nan
df = pd.DataFrame(arr)
print(df)
# 0 1 2
# 0 8.0 NaN 0.0
# 1 1.0 3.0 2.0
# 2 NaN NaN NaN
# 3 6.0 NaN 7.0
# 4 NaN 8.0 5.0
# 5 1.0 4.0 6.0
# 6 NaN NaN NaN
# 7 NaN NaN NaN
# 8 8.0 NaN NaN
# 9 5.0 NaN 2.0
for col in df:
mask = pd.isnull(df[col])
pop = df[col].dropna()
if len(pop):
sample = np.random.choice(pop, size=len(df)-len(pop), replace=True)
df.loc[mask, col] = sample
print(df)
дает такой результат, как
0 1 2
0 8.0 4.0 0.0
1 1.0 3.0 2.0
2 1.0 8.0 2.0
3 6.0 3.0 7.0
4 8.0 8.0 5.0
5 1.0 4.0 6.0
6 1.0 8.0 2.0
7 8.0 4.0 6.0
8 8.0 4.0 7.0
9 5.0 3.0 2.0
df[col]
возвращает серию.Модификация этой серии не гарантирует самого изменения df
.Таким образом,
df[col].replace(sample, np.nan, inplace=True)
изменяет Серию, возвращаемую df[col]
, но не может изменить df
.
Как правило, для обеспечения изменения DataFrame используйте df.loc[...] = ...
или df.iloc[...] = ...
или сгенерируйте новый DataFrame и переназначьте его на df
(например, df = new_df
), или сгенерируйте новый столбец значений и переназначьте его на столбец (например, df[col] = values
).