我如何在pandas / dataframe中执行以下python操作

时间:2020-11-05 16:53:09

标签: python pandas dataframe

下面是我的数据框

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万多行)的简化版本。可以使用循环,但是效率非常低。

enter image description here

2 个答案:

答案 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()来对大于或等于索引且随机加权的行求和。每次迭代都会重新计算权重。
  • 将“值”添加到原始数据帧(对索引值进行分配/联接,无需在添加到df之前对序列进行排序)

作为健全性检查,删除随机权重并观察到这将减少为反向求和运算:

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