在Pandas DataFrame的数学运算中为处理函数分配NaN的问题
我在使用Python的Pandas库处理数据时遇到了一个问题,主要是在进行数学运算时出现了NaN(不是一个数字)的情况。我有一个函数叫做process_mr
,它的目的是处理数据框中每个方程列里指定的数学规则。例如,一个数学规则可能是“A = B + C + D”,这里的A、B、C和D都是数据框中的列名,而这个操作是加法。
这个process_mr
函数应该遍历数据框,计算每一行的数学表达式,并把结果存储在两个不同的数据框里:subtraction_df
用来存放减法结果,boolean_df
用来存放布尔值的评估结果。
以下是相关的代码部分:
# Function to perform mathematical operations on DataFrame columns
def process_mr(df, equation_column, subtraction_df, boolean_df):
if ' = ' in equation_column:
equation_column2 = equation_column.replace(' = ',' == ')
lhs, rhs = equation_column2.split('==')
elif '<=' in equation_column:
equation_column2 = equation_column
lhs, rhs = equation_column2.split('<=')
elif '>=' in equation_column:
equation_column2 = equation_column
lhs, rhs = equation_column.split('>=')
for index, row in df.iterrows():
lhs_list = [x.strip() for x in lhs.split('+')] if '+' in lhs else lhs.split()
rhs_list = [x.strip() for x in rhs.split('+')] if '+' in rhs else rhs.split()
# Insert DataFrame values into lhs_list and rhs_list
lhs_val_list = [row.loc[col] if col != '100' else 100 for col in lhs_list]
rhs_val_list = [row.loc[col] if col != '100' else 100 for col in rhs_list]
# Convert all elements to float
lhs_val_list = [float(x) for x in lhs_val_list]
rhs_val_list = [float(x) for x in rhs_val_list]
if (np.all(np.isnan(lhs_val_list))) or (all(x is None for x in lhs_val_list)) or (np.all(np.isnan(rhs_val_list)) or (all(x is None for x in rhs_val_list))):
# Assign NaN where a Math Check would have been performed
subtraction_df[equation_column][index] = np.nan
boolean_df[equation_column][index] = np.nan
continue # Skips to next iteration
else:
# Assign 0 to any NaNs that exist for lhs_val_list and rhs_val_list (NaN can't be used in a calculation)
lhs_val_list = [x if not np.isnan(x) else 0 for x in lhs_val_list]
rhs_val_list = [x if not np.isnan(x) else 0 for x in rhs_val_list]
# Perform subtraction operation for math rule and assign the result in subtraction_df
subtraction_df[equation_column][index] = np.sum(lhs_val_list) - np.sum(rhs_val_list)
# Evaluate math rule and store the result in boolean_df
row_vals = df.loc[index]
boolean_df[equation_column][index] = eval(equation_column2, row_vals.to_dict())
return subtraction_df, boolean_df
# Loop through equation columns and perform the operation
for col in new_mr_columns_list:
process_mr(df, col, subtraction_df, boolean_df)
使用上面的函数和代码,我原本希望在boolean_df
中由于在评估之前进行了NaN的赋值,能产生更少的假值(False)。然而,结果却是产生了比我预期的更多的假值。你能看到代码中有什么错误或问题吗?谢谢。
1 个回答
0
这里有一些一般性的建议:
- 尽量使用
.iat
或.at
,而不是.loc
,这样会更快。这里有个链接可以了解更多关于这个的内容:点击这里 - 在循环中使用 eval 来评估布尔表达式可能会有风险,而且效率不高。建议你换个方法。
- 我觉得你可以简化你的代码,现在的代码中有太多的列表推导式,这样会让代码变得复杂,也更容易出错。