我有一个示例数据框:
val1 val2 val3 val4 total
0 1 2 3 4 50
1 5 6 4 8 65
2 2 3 6 5 74
我想基于简单的列添加和划分来创建一些新列。每次都会得到一个比例/比率,因此我设置了一个快速功能来做到这一点:
def vectorize(df,value_cols,total_col):
return df[value_cols] / df[total_col]
现在我想获得val1
与total
的比例:
total = 'total'
values = 'val1'
df['result'] = vectorize(df,values,total)
val1 val2 val3 val4 total result
0 1 2 3 4 50 0.020000
1 5 6 4 8 65 0.076923
2 2 3 6 5 74 0.027027
这看起来很棒。
现在,当我想在除以total
之前添加多列时,我遇到了问题。
例如,我尝试找出val1 + val2
与total
的比例:
total = 'total'
values = ['val1','val2']
df['result2'] = vectorize(df,values,total)
ValueError: Wrong number of items passed 5, placement implies 1
这不起作用,因为我的列名现在在列表中。它返回的数据帧为Nans
。
有没有解决这个问题的简单方法?
我尝试将sum()
添加到函数中,但没有得到正确的结果:
return df[value_cols].sum() / df[total_col]
我尝试使用enumerate
将列加在一起,然后除以total
:
for i,col in enumerate(value_cols):
sums = df[col] += df[col]
return sums / df[total_col]
但是这些都不起作用。
我基本上是想在函数中自动化它:
df['val1'] + df['val2'] / df['total']
但是也允许只包含一列,即仅val1
个。
我的现实世界数据框有数百列,我想像这样将一个或多个列加在一起。我可以手动输入所有内容,但我想尝试通过创建矢量化功能来加快速度。
我的df再现性:
import pandas as pd
pd.DataFrame({'val1': pd.Series([1, 5, 2],dtype='int64',index=pd.RangeIndex(start=0, stop=3, step=1)), 'val2': pd.Series([2, 6, 3],dtype='int64',index=pd.RangeIndex(start=0, stop=3, step=1)), 'val3': pd.Series([3, 4, 6],dtype='int64',index=pd.RangeIndex(start=0, stop=3, step=1)), 'val4': pd.Series([4, 8, 5],dtype='int64',index=pd.RangeIndex(start=0, stop=3, step=1)), 'total': pd.Series([50, 65, 74],dtype='int64',index=pd.RangeIndex(start=0, stop=3, step=1))}, index=pd.RangeIndex(start=0, stop=3, step=1))
答案 0 :(得分:1)
这是一种方法:
def vectorize(df,value_cols,total_col):
# for multiple columns
if isinstance(value_cols, list):
return df[value_cols].sum(axis=1) / df[total_col]
# for single column
return df[value_cols] / df[total_col]
答案 1 :(得分:1)
只需调整功能:
def vectorize(df,value_cols,total_col):
if(isinstance(value_cols, list)):
return df[value_cols].apply(sum, axis=1).div(df[total_col])
else:
return df[value_cols].div(df[total_col])
输出:
val1 val2 val3 val4 total result result2
0 1 2 3 4 50 0.020000 0.060000
1 5 6 4 8 65 0.076923 0.169231
2 2 3 6 5 74 0.027027 0.067568
答案 2 :(得分:0)
使用remove_configuration()
是正确的选择。但是您需要指定要添加的轴。默认情况下,它添加行,而不是列。这就是您需要的:
LayoutManager
答案 3 :(得分:0)
由于您需要执行许多除法,因此可以对列进行求和,因此我将对函数进行一些修改。向其传递DataFrame
,分母列,然后传递一个列表列表,这些列表指定基于每个子列表添加的列。
def sum_then_divide(df, total_col, numer_col_list):
"""
df : pd.DataFrame
total_col : str, denominator
numer_col_list: list of lists
Sum all columns in each sublist before dividing
"""
u = pd.concat([df[cols].sum(1).rename('+'.join(cols)) for cols in numer_col_list], axis=1)
return u.divide(df[total_col], axis=0)
sum_then_divide(df, 'total', [['val1'], ['val1', 'val2'], ['val1', 'val3', 'val4']])
# val1 val1+val2 val1+val3+val4
#0 0.020000 0.060000 0.160000
#1 0.076923 0.169231 0.261538
#2 0.027027 0.067568 0.175676