我从数据库中选择了一个数值列的子集,并希望遍历这些列,选择一个,target_column
并将其与数据框中其他两列之间的数值运算结果进行比较。但是,我不确定如何比较结果(例如col1 * col2 = target_column
)。
# For all possible combinations of numeric columns
for col1, col2 in combinations(numeric_cols, 2):
# For a target column in numeric_columns
for target_column in numeric_cols:
# Skip if the target column is one of the relationship columns
if target_column in (col1, col2):
continue
编辑:我已经解决了一些问题,但我仍然不确定这是否是最有效的方法
def analyse_relationships(df):
numeric_cols = df.select_dtypes(include=[np.number])
threshold = 0.001
relationships = []
# For all possible combinations of numeric columns
for col1, col2 in combinations(numeric_cols, 2):
# For a target column in numeric_columns
for target_column in numeric_cols:
# Skip if the target column is one of the relationship columns
if target_column in (col1, col2):
continue
# Calculate different operations
product = numeric_cols[col1] * numeric_cols[col2]
sum_cols = numeric_cols[col1] + numeric_cols[col2]
diff = numeric_cols[col1] - numeric_cols[col2]
if np.allclose(product, numeric_cols[target_column], rtol=threshold):
relationships.append(f"{col1} * {col2} = {target_column}")
elif np.allclose(sum_cols, numeric_cols[target_column], rtol=threshold):
relationships.append(f"{col1} + {col2} = {target_column}")
elif np.allclose(diff, numeric_cols[target_column], rtol=threshold):
relationships.append(f"{col1} - {col2} = {target_column}")
为了解决您的问题,我强烈建议您对数据进行矢量化,并尽可能少地使用 Pandas 操作,因为需要进行大量操作,因此,我们越依赖 NumPy,代码运行速度就越快(NumPy 的核心是用 C 编写的)。
由于需要考虑多个运算(
+
,-
,*
,/
),我们需要计算每个结果并将其与 进行比较target_column
,但我们可以使用布尔掩码(即NumPy 数组)来提高空间效率,该掩码是以布尔值表示表达式 的列target_column == col1 operation col2
。请注意,由于 中可能存在浮点数df
,因此实际上最好使用 ,numpy.isclose()
以便为浮点运算设置阈值。您的代码可能类似于以下内容(我在最后添加了一个小示例):
输出:
复杂性分析
我想指出的是,上面的代码有一定的时间复杂度,当元素数量很大时可能会很慢。
上面的代码必须经过多次循环:
numerical_cols
,即(m choose 2) = m(m-1)/2 ~ O(m^2)
;target
,即O(m - 2) = O(m)
;numpy.isclose()
通过循环遍历每个元素进行的比较n
,因此其复杂度为O(n)
。考虑到这些周期,很容易看出代码的时间复杂度为
O(m^2 * m * n) = O(n * m^3)
,因此所需时间将相对于数值列的数量呈立方增加,并且相对于每列中的元素数量呈线性增加。