You can get the number of rows per country, generate samples for each of them and use the reindex-repeat
strategy (this answer) to expand the samples.
# get size
df_out = df.groupby("country").size().to_frame("size")
# generate sample for each country
df_out[["a","b","c","d"]] = df_out.apply(lambda el: random.sample(nums, k=4), axis=1).to_list()
# ***** Replace the above line with the following code *****
# ***** If it didn't work (legacy pandas version?)***
df_out = pd.concat(
[df_out,
pd.DataFrame([random.sample(nums, k=4) for i in range(len(df_out))],
columns=["a","b","c","d"],
index=df_out.index)
], axis=1)
# repeat rows based on size
df_out = df_out.reindex(df_out.index.repeat(df_out["size"])).reset_index()
Output
print(df_out)
country size a b c d
0 Italy 1 0.5 0.3 0.1 0.7
1 UK 2 0.3 0.5 0.7 0.3
2 UK 2 0.3 0.5 0.7 0.3
3 USA 2 0.7 0.1 0.3 0.1
4 USA 2 0.7 0.1 0.3 0.1
5 Uk 1 0.1 0.7 0.5 0.5 <- caused by typo in given data
Tested on python 3.7, pandas 1.1.3, 64-bit debian 10 OS