熊猫:if和条件应用函数不会返回任何数据

时间:2019-08-07 06:38:40

标签: python pandas

我正在尝试应用.apply函数,该函数使用每行逻辑的 if 来基于其他两个列的值填充一列。 在我的数据集中,我有两列想要在应用所需的查找之前检查行是否合格。在映射数据框中,我将其分为4个单独的数据帧。

1.price per node new - prod
2.price per node new - non prod
3.price per node expansion - prod
4.price per node expansion - non prod

product_and_range_new_prod

   product_and_range_p_n    score_p_n
0   Basic 3-4K             0.090909
1   Basic 5-6K             0.090909
2   Basic 6-7K             0.090909

product_and_range_new_non_prod

      product_and_range_np_n    score_np_n
0        Basic 3-4K               0.0
1        Basic 5-6K               0.0
2        Adv   1-2K               0.2

product_and_range_expansion_prod

     product_and_range_p_e  score_p_e
0        Basic 1-2K         0.230769  
1        Basic 3-4K         0.230769
2        Basic 5-6K         0.230769

product_and_range_expansion_non_prod

     product_and_range_np_e score_np_e
0        Basic 2-3K          0.00
1        Basic 5-6K          0.00
2        Adv 1-2K            0.25

主要DF aka df

    price_per_node  deal_type   product_group
0   NaN             Expansion   None
1   11823.517808    Expansion   Prod
2   6422.994411     New         Prod
3   14045.337803    Expansion   Prod
4   1495.890411     Expansion   Non-Prod

当我尝试应用具有某些逻辑的函数时,如果prod和new应用正确的数据框等,则所有行均无显示。有人可以解释为什么我没有使用返回数据的if语句吗?

这是我的职能

def per_node_price_score(row):

    try:
        if row['deal_type'] == 'New' and row['product_group'] == 'Prod':

            return product_and_range_new_prod.loc[product_and_range_new_prod['product_and_range_p_n'] == row['price_per_node']].iloc[-1]['score_p_n']

        elif row['deal_type'] == 'New' and row['product_group'] == 'Non-Prod':

            return product_and_range_new_non_prod.loc[product_and_range_new_non_prod['product_and_range_np_n'] == row['price_per_node']].iloc[-1]['score_np_n']

        elif row['deal_type'] == 'Expansion' and row['product_group'] == 'Prod':

            return product_and_range_expansion_prod.loc[product_and_range_expansion_prod['product_and_range_p_e'] == row['price_per_node']].iloc[-1]['score_p_e']

        elif row['deal_type'] == 'Expansion' and row['product_group'] == 'Non-Prod':

            return product_and_range_expansion_non_prod.loc[product_and_range_expansion_non_prod['product_and_range_np_e'] == row['price_per_node']].iloc[-1]['score_np_e']

    except: IndexError

df['per_node_price_score'] = df.apply(per_node_price_score, axis=1)

df.head(5)

3 个答案:

答案 0 :(得分:0)

据我所知,您编写的逻辑不应返回任何值。您告诉函数在

时返回索引product_and_range_new_prod
product_and_range_new_prod['product_and_range_p_n'] == row['price_per_node']

但是什么时候发生?您需要稍微不同地组织数据。您想要的是当price_per_node在列出的范围内时返回索引。首先,范围应与基本/高级信息分开。然后,将范围列为两个独立的最大和最小列可能是有意义的,然后使用大于或小于逻辑来查找具有产品价格的正确索引

此外,将四个DataFrame组合在一起并使用其描述性标题作为额外的一列可能是个好主意。最后,如果您遵循所有这些步骤,您的DataFrame将会像这样

   product    min    max    score    type
0   Basic    3000    4000   0.090909 product_and_range_new_prod
1   Basic    5000    6000   0.090909 product_and_range_new_prod
2   Basic    6000    7000   0.090909 product_and_range_new_prod
3   Basic    3000    4000   0.0      product_and_range_new_non_prod
4   Basic    5000    6000   0.0      product_and_range_new_non_prod
5   Adv      1000    2000   0.2      product_and_range_new_non_prod
6   Basic    1000    2000   0.230769 product_and_range_expansion_prod  
7   Basic    3000    4000   0.230769 product_and_range_expansion_prod
8   Basic    5000    6000   0.230769 product_and_range_expansion_prod
9   Basic    2000    3000   0.00     product_and_range_expansion_non_prod
10  Basic    5000    6000   0.00     product_and_range_expansion_non_prod
11  Adv      1000    2000   0.25     product_and_range_expansion_non_prod

另一个问题是您引用了函数中未传递的其他DataFrame。您可以按照documentation的说明向自己的apply函数添加参数,但是可能需要以不同的方式引用变量。

例如,如果您将参数作为kwargs(关键字参数)传递,则必须将其作为字典值进行引用。我在下面写了一个简单的示例

def apply_function(row,**kwargs):
    print(kwargs['key1'])

df.apply(key1='some_variable')

答案 1 :(得分:0)

这是为了澄清一些事情,并解释为什么我认为您的逻辑不起作用以及您的期望:

在您的Apply函数中,您检查deal_typeprod_group。在第一个if子句中,您返回的表达式值等于(只需重新格式化/分配的变量即可一目了然):

value= row['price_per_node']
indexer= product_and_range_new_prod['product_and_range_p_n'] == value
product_and_range_new_prod.loc[indexer].iloc[-1]['score_p_n']

如果我没有错过任何内容,那么indexer将是所有行的False,因为valuefloat的值,而product_and_range_new_prod['product_and_range_p_n']是像Basic 3-4K'这样的字符串,因此返回的内容将一无所有。您可能会为所有行得到一个IndexError

您是要在另一个字段上进行“查找”还是根据索引进行“查找”? 上面的索引似乎并未针对所有数据框对齐,是吗?

在两种情况下,我认为您都可以更有效地进行“查找”。

答案 2 :(得分:0)

这些条件从不满足:

[product_and_range_new_prod['product_and_range_p_n'] == row['price_per_node']
[product_and_range_new_non_prod['product_and_range_np_n'] == row['price_per_node']
[product_and_range_expansion_prod['product_and_range_p_e'] == row['price_per_node']
[product_and_range_expansion_non_prod['product_and_range_np_e'] == row['price_per_node']

这些是正在比较的示例:

df.price_per_node
0             NaN
1    11823.517808
2     6422.994411
3    14045.337803
4     1495.890411
Name: price_per_node, dtype: float64

product_and_range_new_prod.product_and_range_p_n
0    Basic 3-4K
1    Basic 5-6K
2    Basic 6-7K
Name: product_and_range_p_n, dtype: object

if-elif逻辑正常工作:

DataFrame(df

enter image description here

功能

def per_node_price_score(row):

    try:
        if row['deal_type'] == 'New' and row['product_group'] == 'Prod':
            print('1')

        elif row['deal_type'] == 'New' and row['product_group'] == 'Non-Prod':
            print('2')

        elif row['deal_type'] == 'Expansion' and row['product_group'] == 'Prod':
            print('3')

        elif row['deal_type'] == 'Expansion' and row['product_group'] == 'Non-Prod':
            print('4')

    except: IndexError

函数调用

df['per_node_price_score'] = df.apply(per_node_price_score, axis=1)

>>> 3
    1
    3
    4
    2
  • 给定函数调用,我们从输出中可以看到每个if / elif条件都得到满足