下面是我的数据框
df = pd.DataFrame({
'Year': [2021, 2022, 2023, 2024, 2025],
'Tval' : [1, 9, 8, 1, 6]
})
我想创建一个新列,其输出如所附的快照所示。
迅速生成一个乘数(2.3、1.2、1.3、2.6和1.13)。 对于快照2和快照3同样如此。什么是执行此操作的最有效方法,因为它是原始问题(具有3万多行)的简化版本。可以使用循环,但是效率非常低。
答案 0 :(得分:1)
您希望每行的值是后续行与随机值(每次操作重新计算随机值)的乘积。您可以按照以下步骤进行操作:
values = df.sort_index(ascending=False)['Tval']
values = values.expanding().apply(lambda x: np.sum(x*np.random.random(size=len(x))))
df["values"] = values
结果:
Year Tval values
0 2021 1 10.342499
1 2022 9 15.595990
2 2023 8 11.491088
3 2024 1 5.447966
4 2025 6 3.689064
说明:
expanding
对所有行进行操作以获取第一个索引,对最后一行进行操作expanding()
来对大于或等于索引且随机加权的行求和。每次迭代都会重新计算权重。作为健全性检查,删除随机权重并观察到这将减少为反向求和运算:
values = df.sort_index(ascending=False)['Tval']
values = values.expanding().apply(sum)
df["values"] = values
如果权重不需要在迭代之间改变,则可以使用类似的解决方案。正如其他解决方案之一所建议的那样,您还可以预先计算所有随机权重并取一个内积。这将导致内存效率低下,但可能会更快,因为apply
尚未向量化。
答案 1 :(得分:1)
您正在执行的操作是点积,您可以通过将权重设置为0来说明数据的递减使用
weights = np.random.rand(5, 5)
weights = np.tril(weights)
print(weights)
[[0.80446016 0. 0. 0. 0. ]
[0.38560755 0.45014049 0. 0. 0. ]
[0.61068876 0.91918189 0.66418596 0. 0. ]
[0.78442001 0.63551564 0.35635216 0.14712083 0. ]
[0.54315584 0.20083916 0.28262627 0.01919842 0.58714358]]
点积将是weights
的第一行,将其乘以df["Tval"]
的值,然后将这些乘积中的每一个相加。然后,它将使用weights
的第二行并执行相同的操作,但是由于我们将权重的第二行中的第一个值设置为0,因此我们实际上将忽略df["Tval"]
的第一个值并乘以/ sum其余的值。依此类推。
df["value"] = df["Tval"] @ weights
print(df)
Year Tval value
0 2021 1 19.181775
1 2022 9 11.324420
2 2023 8 7.936429
3 2024 1 5.792162
4 2025 6 5.243747