在 DataFrame 中操作数据:如何计算列的平方

Posted

技术标签:

【中文标题】在 DataFrame 中操作数据:如何计算列的平方【英文标题】:Manipulating data in DataFrame: how to calculate the square of a column 【发布时间】:2020-07-09 14:57:41 【问题描述】:

我想计算A列1,2,3,4的平方,用其他计算处理它存储在C列中

using CSV, DataFrames
df = DataFrame(A = 1:4, B = ["M", "F", "F", "M"])
df.C = ((((df.A./2).^2).*3.14)./1000)

有没有更简单的写法?

【问题讨论】:

【参考方案1】:

我不确定你希望公式能缩短多少,但你可以写:

df.C = @. (df.A / 2) ^ 2 * 3.14 / 1000

为了避免到处写.

或者您可以使用transform!,但它不会更短(它的好处是您可以在处理管道中使用它,例如使用 Pipe.jl):

transform!(df, :A => ByRow(a -> (a / 2) ^ 2 * 3.14 / 1000) => :C)

【讨论】:

非常感谢@Bogumił Kamiński 和 Przemyslaw Szufel 两位!由于您的两个答案都一样好,我都赞成他们两个【参考方案2】:

试试这个:

df.D = .5df.A .^2 * 0.00314

解释:

不需要那么多括号 将标量乘以向量在这里与短向量的向量化一样好(最多两个,大约 100 个元素)

使用BenchmarkTools 的简单基准测试:

julia> @btime $df.E = .5*$df.A .^2 * 0.00314;
  592.085 ns (9 allocations: 496 bytes)

julia> @btime $df.F = @. ($df.A / 2) ^ 2 * 0.00314;
  875.490 ns (11 allocations: 448 bytes)

然而,最快的是更长的版本,您可以在其中提供类型信息 @. (df.A::VectorInt / 2) ^ 2 * 0.00314(同样,这很重要,而简称为 DataFrames 并注意这里必须存在 Z 列,因此我们在此处创建它):

julia> @btime begin $df.Z = VectorFloat64(undef, nrow(df));@. $df.Z = ($df.A::VectorInt / 2.0) ^ 2.0 * 0.00314; end;
  162.564 ns (3 allocations: 208 bytes)

【讨论】:

不做广播,正如你所建议的,实际上比广播所有内容要慢得多,因为你分配了 3 次而不是 1 次。 其实它取决于向量的长度(DataFrame的行数)对于短向量代数乘法更快。收支平衡约为 100 行。我编辑了答案。 但这只是由于您基准测试的示例中代码的类型不稳定性。如果你让操作类型稳定广播一切都会更快。 我将类型稳定版本添加到基准测试中,然后确实对于这么短的向量,这速度要快很多倍,但代码有点长:-) 非常感谢@Przemyslaw Szufel 和 Bogumił Kamiński 两位。由于您的两个答案都一样好,我都赞成他们两个

以上是关于在 DataFrame 中操作数据:如何计算列的平方的主要内容,如果未能解决你的问题,请参考以下文章

如何计算Apache Spark DataFrame中所有列的不同值的数量[重复]

如何将计算列添加到源 DataFrame

pandas计算dataframe结束时间列和起始时间列的时间差使用nlargest函数获取dataframe数据时间差前5大的样本数据

pandas使用unique函数计算dataframe单个数据列中的独特值或者计算dataframe多个数据列的独特值(get unique values of column or columns)

pandas使用ewm函数计算dataframe指定数据列的的特定周期指数移动(滚动)平均(Exponential Moving Average)

pandas计算dataframe结束时间列和起始时间列的时间差使用sort_values函数对dataframe数据基于时间差进行排序(设置使用倒序排序)