Я пытаюсь сгенерировать иерархические случайные данные в кадре данных Pandas. В качестве игрушечного примера предположим, что я выбираю x
из некоторого распределения, а затем образец y
из некоторого условного распределения, заданного x
, а затем выборку z
из некоторого условного распределения, заданного x
и y
как показано ниже. В моей реальной проблеме x
, y
и z
могут принимать гораздо больше значений, чем просто 0
и 1
, но распределения представлены с использованием словарей, как показано ниже. Есть ли более элегантный способ сгенерировать этот фрейм данных? Особенно неприятно то, что мне нужно сгенерировать «массив», используя np.random.choice
, а затем просто выбрать один элемент. Кроме того, похоже, что код для генерации z
особенно неудобен, потому что мне нужно извлечь столбцы x
и y
из row
, а не писать что-то вроде lambda x, y: ...
, чтобы строка автоматически сглаживалась в столбцы.
p_x = {0: 0.2, 1: 0.8}
p_y_given_x = {
0: {0: 0.3, 1: 0.7},
1: {0: 0.5, 1: 0.5},
}
p_z_given_x_and_y = {
0: {0: {0: 0.1, 1: 0.9}, 1: {0: 0.5, 1: 0.5}},
1: {0: {0: 0.5, 1: 0.5}, 1: {0: 0.7, 1: 0.3}},
}
data = pd.DataFrame({
'x': np.random.choice(a=list(p_x), size=10, p=list(p_x.values()))
})
data['y'] = data['x'].apply(
lambda x: np.random.choice(
list(p_y_given_x[x]),
size=1,
p=list(p_y_given_x[x].values()),
)[0],
)
data['z'] = data.apply(
lambda row: np.random.choice(
list(p_z_given_x_and_y[row['x']][row['y']]),
size=1,
p=list(p_z_given_x_and_y[row['x']][row['y']].values()),
)[0],
axis=1,
)