我有一个这样的数据框(通常有更多的列和行):
define(['underscoreBase'], function(_) {
var oldTemplate = _.template;
_.template = function(str){
return oldTemplate("<div class='test'>"+str+"</div>");
};
return _;
});
现在,我想将列 A B
0 5 10
1 15 3
和A_ratio
添加到此数据框,其中值分别代表B_ratio
和A/(A + B)
。因此B/(A + B)
和A_ratio
在数据帧的每一行中最多应加1。
我的第一次尝试看起来像这样:
B_ratio
给我以下结果:
import pandas as pd
df = pd.DataFrame({'A': [5,15], 'B': [10,3]})
for coli in df:
df[coli + '_ratio'] = df[coli]/df.sum(axis=1)
显然, A B A_ratio B_ratio
0 5 10 0.333333 0.652174
1 15 3 0.833333 0.159292
列和A_ratio
列不等于1.虽然B_ratio
中的值是正确的,但A_ratio
中的值是错误的,因为行总和是在添加B_ratio
时更改。
解决方法可能是首先复制数据框:
A_ratio
给了我想要的输出:
df2 = pd.DataFrame({'A': [5,15], 'B': [10,3]})
df2cl = df2.copy()
for coli in df2:
df2[coli + '_ratio'] = df2[coli]/df2cl.sum(axis=1)
是否有更有效的方法可以避免复制数据帧?
答案 0 :(得分:2)
您可以从您的df中进行选择,以便它只对这两列进行求和:
In [195]:
for coli in df:
df[coli + '_ratio'] = df[coli]/df[['A','B']].sum(axis=1)
df
Out[195]:
A B A_ratio B_ratio
0 5 10 0.333333 0.666667
1 15 3 0.833333 0.166667
如果您不想对其进行硬编码,您可以提前获取列名的副本:
In [197]:
cols = df.columns
for coli in df:
df[coli + '_ratio'] = df[coli]/df[cols].sum(axis=1)
df
Out[197]:
A B A_ratio B_ratio
0 5 10 0.333333 0.666667
1 15 3 0.833333 0.166667
答案 1 :(得分:2)
您不需要每次都打电话给。
>>%timeit %run multiple_sum.py
100 loops, best of 3: 6.59 ms per loop
>>%timeit %run single_sum.py
100 loops, best of 3: 3.84 ms per loop
如果你有一个大数据帧,这将是不必要的开销。
sums = df.sum(axis=1)
for coli in df:
df[coli + '_ratio'] = df[coli]/sums
就足够了