首页 > 解决方案 > 使用 if-elif-else 语句创建多列和多行

问题描述

我有一个数据df1框,我正在使用它创建产生矩形角的行。根据标签之一是否为S1和之一S2,需要应用不同的功能。现在,数据框如下所示:

Thing  x  y Side  length_x  length_y
0     A  1  3   S1         1         2
1     A  1  1   S2         1         2
2     B  2  3   S1         2         1

为此,我生成了一个列表things = list(set(df1.Thing.unique())),即things =['S1','S2'].

如果SideS1,则需要应用以下函数:

a = df.join(df.apply(lambda r: pd.Series({'corner_x': [r['x']+r['length_x']/2, r['x']-r['length_x']/2],
                                                  'corner_y': [r['y'], r['y']-r['length_y']/2],}),
                             axis=1).explode('corner_x').explode('corner_y'), how='right')

如果SideS2,则需要应用此功能:

b = df.join(df.apply(lambda r: pd.Series({'corner_x': [r['x']+r['length_x']/2, r['x']-r['length_x']/2], 
                                                  'corner_y': [r['y']+r['length_y']/2, r['y']+r['length_y']/2],}), 
                                    axis=1).explode('corner_x').explode('corner_y'),how='right')

它们都独立工作,但我想做的是即时执行此操作。我试过:

dd = []
ee = []
ff = []
for thing in things:
    df = df1[df1['Thing']=='{}'.format(thing)]
    if df['Side']=='S1': 
        a = df.join(df.apply(lambda r: pd.Series({'corner_x': [r['x']+r['length_x']/2, r['x']-r['length_x']/2],
                                                  'corner_y': [r['y'], r['y']-r['length_y']/2],}),
                             axis=1).explode('corner_x').explode('corner_y'), how='right')
        ee.append(a)

    elif df['Side']=='S2':
        b = df.join(df.apply(lambda r: pd.Series({'corner_x': [r['x']+r['length_x']/2, r['x']-r['length_x']/2], 
                                                  'corner_y': [r['y']+r['length_y']/2, r['y']+r['length_y']/2],}), 
                                    axis=1).explode('corner_x').explode('corner_y'),how='right')
        dd.append(b)

    else: 
        0
        
    EE = pd.concat(ee, ignore_index=True)
    DD = pd.concat(dd, ignore_index=True)

Full = pd.concat([EE,DD])

但它确实有效。我收到此错误:

ValueError: The truth value of a Series is ambiguous. Use a.empty, a.bool(), a.item(), a.any() or a.all()

基本上,我试图通过所有案例来做这件事,只有两个可能的案例。我不明白歧义在哪里。要么S1要么S2

我该如何解决这个问题?我尝试过df.assignnp.where但在这两种情况下,我都失败了,因为我正在创建几个列。

感谢您对此的任何帮助。

标签: python-3.xpandas

解决方案


为什么不在申请中将条件放在“Side”上?因此,您不需要循环或在哪里......</p>

df.join(df.apply(lambda r: pd.Series({'corner_x': [r['x']+r['length_x']/2, r['x']-r['length_x']/2],
                                      
                                      'corner_y': [r['y'], r['y']-r['length_y']/2]
                                                  if r['Side'] == 'S1' else
                                                  [r['y']+r['length_y']/2, r['y']+r['length_y']/2],
                                     }),
                 
                             axis=1).explode('corner_x').explode('corner_y'), how='right')

输出:

  Thing  x  y Side  length_x  length_y corner_x corner_y
0     A  1  3   S1         1         2      1.5        3
0     A  1  3   S1         1         2      1.5        2
0     A  1  3   S1         1         2      0.5        3
0     A  1  3   S1         1         2      0.5        2
1     A  1  1   S2         1         2      1.5        2
1     A  1  1   S2         1         2      1.5        2
1     A  1  1   S2         1         2      0.5        2
1     A  1  1   S2         1         2      0.5        2
2     B  2  3   S1         2         1        3        3
2     B  2  3   S1         2         1        3      2.5
2     B  2  3   S1         2         1        1        3
2     B  2  3   S1         2         1        1      2.5

推荐阅读