【问题标题】:Comparing pandas dataframe with predefined limits将熊猫数据框与预定义的限制进行比较
【发布时间】:2021-12-28 18:26:05
【问题描述】:

我有一个具有以下结构的熊猫数据框。它包含之前完成的比较结果,minimum_difference 列显示了该行的哪一列包含该比较中较小的绝对差异。

df_test

V       |  A    | B   |  C      |  D    | minimum_difference
-10     |  nan  | nan |  nan    |  nan  | nan
-9.9    |  10   | 1   |  -2200  |  100  | B
-9.8    |  11   | 2   |  -2211  |  1    | D

另外,我为每个值列(A、B、C、D)的最小差异设定了目标最大差异,如下所示:

max_difference = pd.Series(dict(
    A=1,
    B=2,
    C=10,
    D=0.5,
))

我想向 df_test 添加一个新列,该列将最小差异与该列的目标值进行比较。例如:

V       |  A    | B   |  C      |  D    | minimum_difference | is_within_max_target
-10     |  nan  | nan |  nan    |  nan  | nan                | nan
-9.9    |  10   | 1   |  -2200  |  100  | B                  | TRUE
-9.8    |  11   | 2   |  -2211  |  1    | D                  | FALSE

非常欢迎任何意见和想法!

【问题讨论】:

  • 我只是要求澄清一下。在最后一个数据帧中,第 3 行,is_within_max_targetFALSE,因为 ((-9.8-2)= -11.8) > D=0.5 ?
  • 该值为假,因为最小差异在 D 列中,其值为 1,而 D 的最大差异为 0.5。

标签: python python-3.x pandas dataframe


【解决方案1】:

这是一个矢量化解决方案(快速):

# first: the minimum difference

# we use all names defined in the max_difference Series
cols = max_difference.index.tolist()
z = df_test[cols].abs()
df_test['minimum_difference'] = z.idxmin(axis=1)


# second: whether that difference is <= the corresponding max_difference
i = np.argmin(z.values, axis=1)
df_test['is_within_max_target'] = z.values[np.arange(len(i)), i] <= max_difference.values[i]

请注意,为了同质性(dtype=bool 用于最后一列),我们不会在该列中携带 NaN

【讨论】:

  • 感谢您的回答 :) 我试图理解它,“[list('ABCD')]” 传递字符串中的所有列名?如何/在哪里可以传递“max_difference”中的参数?
  • 我只是在解决问题的第一部分。我更新了答案以解决两个子问题。请注意,这是矢量化且快速的(没有apply)。
【解决方案2】:

一种方法是对每一行应用一个函数(非矢量化;对于您的完整数据集可能不够快,也可能不够快):

def check_diffs(row):
    col = row['minimum_difference']
    if col is np.nan:
        return np.nan
    else:
        return row[col] <= max_difference[col]

df_test['is_within_max_target'] = df_test.apply(check_diffs, axis=1)

print(df_test)
# Output given your example data:
      V     A    B       C      D minimum_difference is_within_max_target
0 -10.0   NaN  NaN     NaN    NaN                NaN                  NaN
1  -9.9  10.0  1.0 -2200.0  100.0                  B                 True
2  -9.8  11.0  2.0 -2211.0    1.0                  D                False

【讨论】:

    【解决方案3】:

    我试图让它尽可能简单:

    import pandas as pd 
    import math
    data = [[-10 , math.nan, math.nan, math.nan, math.nan, math.nan],
            [-9.9, 10 , 1 , -2200, 100, 'B'],
            [-9.8, 11 , 2 , -2211, 1, 'D']]
    df_test = pd.DataFrame(data, columns = ['V', 'A', 'B' , 'C', 'D', 'minimum_difference'])
    
    
    max_difference = {
                        'A':1,
                        'B':2,
                        'C':10,
                        'D':0.5}
    
    df_result= pd.DataFrame(columns = ['V', 'A', 'B' , 'C', 'D', 'minimum_difference', 'is_within_max_target'])
    
    
    for i in range(0, len(df_test)):
                   current_row = df_test.iloc[i].tolist()
                   current_diff_column = str(current_row[5])
               
                   if(current_diff_column!='nan'):
                       current_value = df_test[current_diff_column].iloc[i]
                       if(current_value <= max_difference[current_diff_column]):
                           current_row.append('True')
                           df_result.loc[len(df_result)] = current_row
                       else:
                           current_row.append('False')
                           df_result.loc[len(df_result)] = current_row
                   else:
                       current_row.append(math.nan)
                       df_result.loc[len(df_result)] = current_row
               
                   
    print(df_result)
    

    输出:

          V     A    B       C      D minimum_difference is_within_max_target
    0 -10.0   NaN  NaN     NaN    NaN                NaN                  NaN
    1  -9.9  10.0  1.0 -2200.0  100.0                  B                 True
    2  -9.8  11.0  2.0 -2211.0    1.0                  D                False
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2022-12-13
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-10-23
      相关资源
      最近更新 更多