Я хотел бы знать, как заполнить столбец полярного фрейма данных случайными значениями. Идея состоит в том, что у меня есть фрейм данных с заданным количеством столбцов, и я хочу добавить столбец в этот фрейм данных, который заполнен различными случайными значениями (например, полученными из функции random.random()).
Это то, что я пробовал на данный момент:
df = df.with_columns(pl.when((pl.col('Q') > 0)).then(random.random()).otherwise(pl.lit(1)).alias('Prob'))
С помощью этого метода результат, который я получаю, представляет собой столбец, заполненный одним случайным значением, т.е. все строки имеют одинаковое значение.
Есть ли способ заполнить столбец разными случайными значениями?
Спасибо заранее.
Сначала получите количество строк вашего фрейма данных:
row_n = df.select(pl.count()).collect().items()
Затем создайте случайный список такого размера, используя random:
to_add = random.sample(range(0, 10), row_n)
И, наконец, добавьте его в свой фрейм данных:
df.with_column(pl.Series(name = "new_col", values=to_add))
Вы можете сделать:
df.with_columns(
pl.Series(
[random.random() if q > 0 else 1 for q in df["Q"]]
).alias("Prob")
)
Вам нужен «столбец» случайных чисел той же высоты, что и ваш фрейм данных.
np.random.rand
пригодится для этого:
>>> df.with_columns(random = pl.lit(np.random.rand(df.height)))
shape: (3, 2)
┌─────┬──────────┐
│ foo ┆ random │
│ --- ┆ --- │
│ i64 ┆ f64 │
╞═════╪══════════╡
│ 1 ┆ 0.51566 │
│ 2 ┆ 0.009299 │
│ 3 ┆ 0.519169 │
└─────┴──────────┘
>>> df.with_columns(random = pl.when(pl.col("foo") > 2).then(pl.lit(np.random.rand(df.height))))
shape: (3, 2)
┌─────┬──────────┐
│ foo ┆ random │
│ --- ┆ --- │
│ i64 ┆ f64 │
╞═════╪══════════╡
│ 1 ┆ null │
│ 2 ┆ null │
│ 3 ┆ 0.926295 │
└─────┴──────────┘
Создайте образец фрейма данных polars
df = pl.DataFrame({
'Q': [1, -1, -3, 4],
})
Однострочный векторизованный расчет
df = df.with_columns(
pl.when(pl.col('Q') > 0)
.then(pl.lit(np.random.uniform(0, 1, len(df))))
.otherwise(1)
.alias('Prob')
)
Результат
Q Prob
1 0.922802
-1 1.0
-3 1.0
4 0.182397
Во-первых, вы используете относительно старую версию polars, если вы все еще используете with_column
, а не with_columns
, поэтому я бы рекомендовал обновить ее, так как появились новые функции и улучшения производительности. Есть также критические изменения, такие как with_column
, поскольку они были излишними, учитывая, что это была просто ограниченная версия with_columns
с самого начала.
Отложив это в сторону, и к вашей проблеме, причина, по которой она не работает, заключается в том, что когда вы запускаете
df.with_columns(pl.when((pl.col('Q') > 0)).then(random.random()).otherwise(pl.lit(1)).alias('Prob'))
python вызывает random.random()
только один раз, и, поскольку он возвращает только одно значение, polars транслирует (то есть копирует) его во все строки. Что вам нужно сделать, так это сказать python запускать его все время, когда вам это действительно нужно. Я помещаю need в кавычки, потому что поляры будут жаловаться, если вы попытаетесь дать меньше значений, чем вся высота df, даже если вам нужно только столько случайных значений, сколько есть Q>0.
Самый простой способ сделать это — просто добавить понимание списка в высоту df
df.with_columns(
pl.when((pl.col('Q') > 0))
.then(pl.lit([random.random() for _ in range(df.height)]))
.otherwise(pl.lit(1))
.alias('Prob'))
Использование понимания списка для random.random()
не так эффективно, как использование numpy для создания массива случайных чисел, поскольку для этого используется оптимизированный код C, тогда как понимание списка — это просто цикл Python. Я собирался ответить на общий вопрос, почему это не работает, а не прописывать метод максимально быстрой генерации случайных чисел.