我需要计算一些交易证券的横截面排名。考虑以下几点
pl.DataFrame
长(整齐)格式。它由三个不同的交易品种组成,每个品种都有一个专用的(即本地)交易日历。
df = pl.DataFrame(
{
"symbol": [*["symbol1"] * 6, *["symbol2"] * 5, *["symbol3"] * 5],
"date": [
"2023-12-30", "2023-12-31", "2024-01-03", "2024-01-04", "2024-01-05", "2024-01-06",
"2023-12-30", "2024-01-03", "2024-01-04", "2024-01-05", "2024-01-06",
"2023-12-30", "2023-12-31", "2024-01-03", "2024-01-04", "2024-01-05",
],
"price": [
100, 105, 110, 115, 120, 125,
200, 210, 220, 230, 240,
3000, 3100, 3200, 3300, 3400,
],
}
)
print(df)
shape: (16, 3)
âââââââââââ¬âââââââââââââ¬ââââââââ
â symbol â date â price â
â --- â --- â --- â
â str â str â i64 â
âââââââââââªâââââââââââââªââââââââ¡
â symbol1 â 2023-12-30 â 100 â
â symbol1 â 2023-12-31 â 105 â
â symbol1 â 2024-01-03 â 110 â
â symbol1 â 2024-01-04 â 115 â
â symbol1 â 2024-01-05 â 120 â
â ⦠â ⦠â ⦠â
â symbol3 â 2023-12-30 â 3000 â
â symbol3 â 2023-12-31 â 3100 â
â symbol3 â 2024-01-03 â 3200 â
â symbol3 â 2024-01-04 â 3300 â
â symbol3 â 2024-01-05 â 3400 â
âââââââââââ´âââââââââââââ´ââââââââ
第一步是使用以下公式计算周期性回报
pct_change
随后使用
pivot
以对齐每个日期的符号。
returns = df.drop_nulls().with_columns(
pl.col("price").pct_change(n=2).over("symbol").alias("return")
).pivot(on="symbol", index="date", values="return")
print(returns)
shape: (6, 4)
ââââââââââââââ¬âââââââââââ¬âââââââââââ¬âââââââââââ
â date â symbol1 â symbol2 â symbol3 â
â --- â --- â --- â --- â
â str â f64 â f64 â f64 â
ââââââââââââââªâââââââââââªâââââââââââªâââââââââââ¡
â 2023-12-30 â null â null â null â
â 2023-12-31 â null â null â null â
â 2024-01-03 â 0.1 â null â 0.066667 â
â 2024-01-04 â 0.095238 â 0.1 â 0.064516 â
â 2024-01-05 â 0.090909 â 0.095238 â 0.0625 â
â 2024-01-06 â 0.086957 â 0.090909 â null â
ââââââââââââââ´âââââââââââ´âââââââââââ´âââââââââââ
下一步是使用
concat_list
创建a
list
计算每行的排名(降序,即最高返回值为排名1)。
ranks = (
returns.with_columns(all_symbols=pl.concat_list(pl.all().exclude("date")))
.select(
pl.all().exclude("all_symbols"),
pl.col("all_symbols")
.list.eval(
pl.element().rank(descending=True, method="ordinal").cast(pl.UInt8)
)
.alias("rank"),
)
)
print(ranks)
shape: (6, 5)
ââââââââââââââ¬âââââââââââ¬âââââââââââ¬âââââââââââ¬âââââââââââââââââââââ
â date â symbol1 â symbol2 â symbol3 â rank â
â --- â --- â --- â --- â --- â
â str â f64 â f64 â f64 â list[u8] â
ââââââââââââââªâââââââââââªâââââââââââªâââââââââââªâââââââââââââââââââââ¡
â 2023-12-30 â null â null â null â [null, null, null] â
â 2023-12-31 â null â null â null â [null, null, null] â
â 2024-01-03 â 0.1 â null â 0.066667 â [1, null, 2] â
â 2024-01-04 â 0.095238 â 0.1 â 0.064516 â [2, 1, 3] â
â 2024-01-05 â 0.090909 â 0.095238 â 0.0625 â [2, 1, 3] â
â 2024-01-06 â 0.086957 â 0.090909 â null â [2, 1, null] â
ââââââââââââââ´âââââââââââ´âââââââââââ´âââââââââââ´âââââââââââââââââââââ
现在我们终于到了真正的问题:
我想取消象牙
ranks
再次生成一个整洁的数据帧。我正在寻找以下栏目:
symbol
,
date
,
return
,以及
rank
。我在考虑创建三个新列(基本上使用
explode
解压缩列表,但这只会创建新行而不是列)。
此外,我想知道我是否需要转向
df
首先,或者如果有更好的方法直接对原件进行操作
df
整齐的格式?我实际上是在寻找表演
df
可能有数百万行。