有条件的列创建DF Pandas

时间:2018-07-12 10:08:08

标签: python python-3.x pandas

我在创建基于布尔条件的列时遇到麻烦,该布尔条件在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列。

谢谢

1 个答案:

答案 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相比,这是一个微不足道的循环,您将看到显着的性能优势。