仅对数字列求和,然后将值除以总计

时间:2019-06-23 02:25:50

标签: r

我在数据帧上进行一些计算时遇到麻烦。

这是我的DF(有更多的行和列)

我想做的是:

步骤(1)-我想每月汇总资产列。例如 所有资产_2018年1月_并作为DF输出。

步骤(2)-然后,对于每个公司,我想将每个月的资产除以该月的总数,即步骤(1)中计算出的值。例如, 公司A Jan_2018 = 210234/1466742 = 0.14334

步骤(3)-然后我想从步骤(2)中获取值,然后乘以相应的收益。 = 0.143334 * 4.5 = 0.645003

步骤(4)-最后,我想对步骤(3)中的每一列求和并作为DF输出

 Firm   Assets_Jan_2018  Assets_ Feb_2018 Returns_Jan_2018 Returns_Feb_2018
 A          210234             235425           4.5            6.7
 B          123144             127124           5.3            1.2
 c          897897             789798           1.4            6.2
 D          235467             897342           9.7            3.2

我尝试了colSums和其他很多方法,但是一直收到错误消息。

2 个答案:

答案 0 :(得分:3)

我们可以首先分隔"Assets""Returns"列,然后使用colSums并相应地乘以值

asset_col <- grep("^Assets", names(df1))
return_col <- grep("^Returns", names(df1))
colSums(t(t(df1[asset_col])/colSums(df1[asset_col])) * df1[return_col])

#Returns_Jan_2018 Returns_Feb_2018 
#        3.504230         4.633941 

要分解并明确每个步骤

第1步-我想每月汇总资产列

colSums(df1[asset_col])
#Assets_Jan_2018 Assets_Feb_2018 
#    1466742         2049689 

第2步-对于每个公司,我想将每个月的资产除以该月的总数

t(t(df1[asset_col])/colSums(df1[asset_col]))
#     Assets_Jan_2018 Assets_Feb_2018
#[1,]      0.14333400      0.11485889
#[2,]      0.08395751      0.06202112
#[3,]      0.61217106      0.38532577
#[4,]      0.16053744      0.43779422

第3步-然后,我想取第(2)步中的值,然后乘以相应的回报

t(t(df1[asset_col])/colSums(df1[asset_col])) * df1[return_col]

#  Returns_Jan_2018 Returns_Feb_2018
#1        0.6450030       0.76955455
#2        0.4449748       0.07442534
#3        0.8570395       2.38901980
#4        1.5572131       1.40094151

第4步-我想对第(3)步中的每一列求和

colSums(t(t(df1[asset_col])/colSums(df1[asset_col])) * df1[return_col])

#Returns_Jan_2018 Returns_Feb_2018 
#        3.504230         4.633941 

答案 1 :(得分:1)

可能比Ronak的答案要简洁得多,但演示了扫掠功能。

构建示例df:

df['date_listed_to_sale'] = (df['date_sold'] - df['date_listed']).dt.days
print df['date_listed_to_sale'][:5]



TypeErrorTraceback (most recent call last)
<ipython-input-139-85a5efbde0f1> in <module>()
----> 1 df['date_listed_to_sale'] = (df['date_sold'] - df['date_listed']).dt.days
      2 print df['date_listed_to_sale'][:5]

/Users/virt_env/virt1/lib/python2.7/site-packages/pandas/core/ops.pyc in wrapper(left, right)
   1581             rvalues = rvalues.values
   1582 
-> 1583         result = safe_na_op(lvalues, rvalues)
   1584         return construct_result(left, result,
   1585                                 index=left.index, name=res_name, dtype=None)

/Users/virt_env/virt1/lib/python2.7/site-packages/pandas/core/ops.pyc in safe_na_op(lvalues, rvalues)
   1531             if is_object_dtype(lvalues):
   1532                 return libalgos.arrmap_object(lvalues,
-> 1533                                               lambda x: op(x, rvalues))
   1534             raise
   1535 

pandas/_libs/algos.pyx in pandas._libs.algos.arrmap()

/Users/virt_env/virt1/lib/python2.7/site-packages/pandas/core/ops.pyc in <lambda>(x)
   1531             if is_object_dtype(lvalues):
   1532                 return libalgos.arrmap_object(lvalues,
-> 1533                                               lambda x: op(x, rvalues))
   1534             raise
   1535 

TypeError: ufunc subtract cannot use operands with types dtype('S1') and dtype('<M8[ns]')

确保数字数据类型:

df <- data.frame(cbind(Firm = c("A", "B", "C", "D"),
                       Assets_Jan_2018 = as.numeric(c(210234, 123144, 897897, 235467)),
                       Assets_Feb_2018 = as.numeric(c(235425, 127124, 789798, 897342)),
                       Returns_Jan_2018 = as.double(c(4.5,  5.3,  1.4, 9.7)),
                       Returns_Feb_2019 = as.double(c(6.7, 1.2, 6.2, 3.2))))

计算加权收益:

df <- type.convert(df)

总结为df:

FirmWeightedReturns <- cbind(Firm = df$Firm,
                             sweep(df[sapply(df, is.numeric) & !(grepl("returns", tolower(colnames(df))))],
                                   2,
                                   as.numeric(sapply(df[sapply(df, is.numeric) & !(grepl("returns", tolower(colnames(df))))], sum)), '/')
                                  * df[grepl("returns", tolower(colnames(df)))])

输出到控制台:

TotalReturns <- data.frame(lapply(FirmWeightedReturns[sapply(FirmWeightedReturns, is.numeric)], sum))