我正在尝试应用.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)
答案 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_type
和prod_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
,因为value
是float
的值,而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
逻辑正常工作:df
)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
条件都得到满足