Olá Miguel tudo bem com você??
Primeiramente, "row" significa "linha", esse contexto é colocado quando utilizamos uma matriz. Você também irá encontrar "column" que trata das "colunas" da matriz. A matriz é o famoso "df" ou DataFrame que você poderá visualizar no exemplo a seguir:
fonte da imagem e detalhes da utilização de "rows" e "columns"
Agora explicando diretamente a questão do código após o "#" de comentário hehe:
for index, row in nomes.iterrows(): #Aqui é iniciado a construção do novo DataFrame onde mostra que será criado o index e linha que vai utilizar. Linha a linha as informações com o id do aluno e curso dentro de "Nomes". O recurso de linha a linha é o .iterrows()
id = row.id_aluno #Aqui armazena o ID do aluno
matriculas = row.matriculas #Aqui a quantidade de matrículas do aluno
for i in range(matriculas): #Um for para sugerir quantos cursos iremos escolher baseado no número de matrículas dele.
mat = [id, np.random.choice(cursos.index, p = prob)] #Aqui declara uma variável chamada mat para armazenar a escolha do curso
todas_matriculas.append(mat) #Aqui atribuir, somar a matrícula do curso nova as outras matrículas do aluno
matriculas = pd.DataFrame(todas_matriculas, columns = ['id_aluno', 'id_curso']) # Finalizando com a criação propriamente dita do novo DF com as matrículas adicionadas pelos nossos "for" a variável "todas_matriculas".
Deixarei o link da documentação para você conhecer mais sobre .iterrows().
Espero que tenha ficado mais claro como foi feito e sua dúvida tenha sido resolvida =)
Se precisar de ajuda é só retornar aqui tá bom?
Bons estudos!