我在创建基于布尔条件的列时遇到麻烦,该布尔条件在True时映射3列的总和,在False时映射相同的三列的平均值。我看到了一些可以映射简单字符串标识符的堆栈问题,但似乎无法使我的方程式起作用。我用一个非常笨拙的函数方法解决了我的问题,我也将展示它。但是,想看看是否有人对创建字段的更有效和潜在动态的方法有解决方案。
数据:
a = df['man'].map(lambda x: (df['01-18']+df['02-18']+df['03-18']) if x == True else (df['01-18']+df['02-18']+df['03-18'])/3 )
a = df['man'].map((df['01-18']+df['02-18']+df['03-18']) if df['man']==True else (df['01-18']+df['02-18']+df['03-18'])/3 )
a = df.map((df['01-18']+df['02-18']+df['03-18']) if df['man']==True else (df['01-18']+df['02-18']+df['03-18'])/3 )
这些要么抛出错误,要么创建一个列表列表,这些列表我不容易添加为列:
def boolAgg(vals):
d=[]
for ind,val in enumerate(vals):
if val == True:
d.append(df.iloc[ind,0]+df.iloc[ind,1]+df.iloc[ind,2])
else:
d.append((df.iloc[ind,0]+df.iloc[ind,1]+df.iloc[ind,2])/3)
return d
df['Q_1'] = boolAgg(df['man'])
我的函数将为我提供所需的信息(基于df ['man']的季度总和或平均值,但我必须重新定义列索引才能获取下一个季度:
def boolAgg(vals):
d=[]
for ind,val in enumerate(vals):
if val == True:
d.append(df.iloc[ind,3]+df.iloc[ind,4]+df.iloc[ind,5])
else:
d.append((df.iloc[ind,3]+df.iloc[ind,4]+df.iloc[ind,5])/3)
return d
df['Q_2'] = boolAgg(df['man'])
得到Q1,现在我重新定义并运行Q2:
{{1}}
有没有更简单的方法来做到这一点?完美的解决方案将能够使用可能方程式的字典(std.dev,sum,Average等,因此不仅可以映射布尔T / F),而且还可以使用循环自动获取接下来的三列作为集合(即每季度复制3个月-制定一个季度时间序列)并创建Q2,Q3等。 Qn列。
谢谢
答案 0 :(得分:2)
对于简单的布尔条件,不应使用pd.Series.map
或手动进行行迭代。相反,您可以使用numpy.where
。
例如,替换以下内容...
a = df['man'].map(lambda x: (df['01-18']+df['02-18']+df['03-18']) if x == True \
else (df['01-18']+df['02-18']+df['03-18'])/3 )
...具有矢量化逻辑:
sums_1_2_3 = df[['01-18', '02-18', '03-18']].sum(axis=1)
df['new_col'] = np.where(df['man'], sums_1_2_3, sums_1_2_3 / 3)
或者:
sum_1_2_3 = df[['01-18', '02-18', '03-18']].sum(axis=1)
mean_1_2_3 = df[['01-18', '02-18', '03-18']].mean(axis=1)
df['new_col'] = np.where(df['man'], sum_1_2_3, mean_1_2_3)
除了使代码更整洁外,这还将确保您使用的是Pandas数据框下面的NumPy数组。与pd.Series.map
+ lambda
相比,这是一个微不足道的循环,您将看到显着的性能优势。