基于多条件逻辑的单独的熊猫数据范围的返回字符串



我是Python的新手,并尝试使用Pandas中的DataFrames进行一些工作

左侧是主要数据框架(DF1(的部分,右侧是第二个(DF2(。目标是用基于几个条件逻辑的字符串填充DF1 ['vd_type']列。我可以通过Nested NP.Where((函数来完成这项工作,但是随着层次结构的深度,它的运行时间太长了,所以我正在寻找一个更优雅的解决方案。

逻辑的英文版本是:对于df1 ['vd_type']:如果df1 ['shape'] == df2 ['vd_combo']中的前两个字符和df1 ['vd_pct']< = df2 ['combo_value'],然后返回最后3个df2 ['vd_combo']中的字符在这两个条件都是正确的行上。如果在两个条件都是TRUE的DF2中找不到一条线,请返回" VD4"。

预先感谢!


编辑#2:因此,我想基于另一个变量实现第三个条件,其他所有内容都相同,除了在DF1中,还有另一列" log_vsc",其目标是填充空的DF1列" VSC_TYPE"列在同一方案中具有4个字符串之一。额外的条件就是我们刚刚定义的" vd_type"将匹配由split'vsc_combo'引起的" vd"列。

df3 = pd.DataFrame()
df3['vsc_combo'] = ['A1_vd1_vsc1','A1_vd1_vsc2','A1_vd1_vsc3','A1_vd2_vsc1','A1_vd2_vsc2' etc etc etc
df3['combo_value'] = [(number), (number), (number), (number), (number), etc etc
df3[['shape','vd','vsc']] = df3['vsc_combo'].str.split('_', expand = True)
def vsc_condition( row, df3):
    df_select = df3[(df3['shape'] == row['shape']) & (df3['vd'] == row['vd_type']) & (row['log_vsc'] <= df3['combo_value'])]
    if df_select.empty:
        return 'vsc4'
    else:
        return df_select['vsc'].iloc[0]
## apply vsc_type
df1['vsc_type'] = df1.apply( vsc_condition, args = ([df3]), axis = 1)

这有效!!再次感谢!

,因此您的输入就像:

import pandas as pd
df1 = pd.DataFrame({'shape': ['A2', 'A1', 'B1', 'B1', 'A2'],
                    'vd_pct': [0.78, 0.33, 0.48, 0.38, 0.59]} )
df2 = pd.DataFrame({'vd_combo': ['A1_vd1', 'A1_vd2', 'A1_vd3', 'A2_vd1', 'A2_vd2', 'A2_vd3', 'B1_vd1', 'B1_vd2', 'B1_vd3'],
                    'combo_value':[0.38, 0.56, 0.68, 0.42, 0.58, 0.71, 0.39, 0.57, 0.69]} )

如果您不反对在df2中创建列(如果这是问题的话,可以在最后删除它们(,则通过分配vd_combo列来生成两列shapevd

df2[['shape','vd']] = df2['vd_combo'].str.split('_',expand=True)

然后,您可以创建一个将在apply中使用的函数condition,例如:

def condition( row, df2):
   # row will be a row of df1 in apply
   # here you select only the rows of df2 with your conditions on shape and value
   df_select = df2[(df2['shape'] == row['shape']) & (row['vd_pct'] <= df2['combo_value'])]
   # if empty (your condition not met) then return vd4
   if df_select.empty:
       return 'vd4'
   # if your condition met, then return the value of 'vd' the smallest
   else:
       return df_select['vd'].iloc[0]

现在,您可以使用:

df1中创建列vd_type
df1['vd_type'] = df1.apply( condition, args =([df2]), axis=1)

df1就像:

  shape  vd_pct vd_type
0    A2    0.78     vd4
1    A1    0.33     vd1
2    B1    0.48     vd2
3    B1    0.38     vd1
4    A2    0.59     vd3

最新更新