Python 条件列创建
我在创建一个基于布尔条件的列时遇到了问题,该布尔条件映射了3列之和(如果为True)和相同3列的平均值(如果为False)。我看到了一些堆栈问题,这些问题可以映射简单的字符串标识符,但似乎无法使我的方程起作用。我用一个非常笨重的函数方法解决了我的问题,我也将展示这个方法。但我想看看是否有人有一个更有效和潜在的动态方式创建字段的解决方案 数据: 它们要么抛出错误,要么创建一个列表,我无法轻松将其添加为列:Python 条件列创建,python,python-3.x,pandas,Python,Python 3.x,Pandas,我在创建一个基于布尔条件的列时遇到了问题,该布尔条件映射了3列之和(如果为True)和相同3列的平均值(如果为False)。我看到了一些堆栈问题,这些问题可以映射简单的字符串标识符,但似乎无法使我的方程起作用。我用一个非常笨重的函数方法解决了我的问题,我也将展示这个方法。但我想看看是否有人有一个更有效和潜在的动态方式创建字段的解决方案 数据: 它们要么抛出错误,要么创建一个列表,我无法轻松将其添加为列: a = df['man'].map(lambda x: (df['01-18']+df['
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 )
我的函数将得到我所需要的(季度总和或基于df['man']的平均值),但我必须重新定义列索引以获得下一个季度:
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'])
获取Q1,现在我重新定义并运行Q2:
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'])
有没有更简单的方法可以做到这一点?一个完美的解决方案是能够使用可能的方程字典(std.dev、sum、average等,因此可以映射的不仅仅是布尔T/F),并且能够使用循环自动将下三列作为集合(即在一个季度复制3个月,以开发一个季度时间序列)以及创建Q2、Q3、…Qn列
谢谢,对于简单的布尔条件,您不应该使用
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
,这只是一个薄薄的循环相比,您将看到显著的性能优势。不确定这是否会有很大的不同,但另一种选择是:aggs=df['01-18','02-18','03-18']].T.agg(['sum','mean'])
-然后np.where(df['man'],aggs.loc['sum'],aggs.loc['mean'])
..@JonClements,是一个很好的选择:)。我想先得到OP的认可,这是他想要的东西。假设df[…].T.agg(…).T
是一个选项,因为出于某种原因,那些.loc
s让我讨厌…太美了!现在我必须设计一个循环计划来选择接下来的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)