在 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
(同样,这很重要,而简称为 DataFrame
s 并注意这里必须存在 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中所有列的不同值的数量[重复]
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数据基于时间差进行排序(设置使用倒序排序)