【问题标题】:python (Pandas) output value from column 0 based on criteria different columns meetpython(Pandas)根据不同列满足的标准从第0列输出值
【发布时间】:2017-05-25 11:26:00
【问题描述】:

我有两个 pandas 数据框,dfA 和 dfB。 dfA 有一个未知的列数,比如说 x。 dfB 是一个具有 x – 1 个值的 numpy 数组。因此,如果 dfA 有 50 列(0 到 49),那么 dfB 将有 49 个值。这 49 个值与 dfA 列 1-49 相关联。

我需要从 dfA 的第 0 列输出最接近后续列中 dfB 中相应值的行的值。我知道这句话毫无意义。这是一个例子:

dfA:                
0   0.02    0.06    0.09    0.10
1   0.92    0.82    0.71    0.61
2   0.92    0.82    0.72    0.62
3   0.94    0.84    0.74    0.64
4   0.96    0.86    0.76    0.66
5   0.98    0.88    0.78    0.68


dfB:                
    0.94    0.862   0.732   0.623


Answer: 3   4   3   2

我一直在尝试使用 pandas 查询功能或 loc/iloc 功能来做到这一点,但还没有找到解决方案。

【问题讨论】:

    标签: python pandas dataframe boolean range


    【解决方案1】:

    subdfA中减去array dfB的值,用abs得到绝对值,最后用idxmin找到最小值的index

    print (dfA.sub(dfB, axis=1).abs().idxmin())
    1    3
    2    4
    3    3
    4    2
    dtype: int64
    

    【讨论】:

    • 谢谢你,杰兹瑞尔。输出全部为 NaN。 dfA 或 dfB 中没有 NaN。
    【解决方案2】:

    使用 NumPy -

    a = df.values
    out = a[np.abs(a[:,1:] - dfB.values.ravel()).argmin(0),0]
    

    基本上,我们从dfA 的每一行中减去dfB,并且由于我们使用的是NumPy 数组(正如我们用.values 提取的那样),这些在broadcasted manner 中被有效地减去。然后,我们用.argmin(axis=0),简而言之.argmin(0),找到绝对值并沿着每一列寻找arg-minimum。

    如果您也在使用NaNs,请使用np.nanargmin 忽略这些。

    逐步运行示例以使事情更容易理解 -

    # Extract array from dfA
    In [9]: a = dfA.values
    
    # Slice a from col-1 onwards and perform broadcasted differencing with dfB values
    In [10]: a[:,1:] - dfB.values.ravel() 
    Out[10]: 
    array([[-0.92 , -0.802, -0.642, -0.523],
           [-0.02 , -0.042, -0.022, -0.013],
           [-0.02 , -0.042, -0.012, -0.003],
           [ 0.   , -0.022,  0.008,  0.017],
           [ 0.02 , -0.002,  0.028,  0.037],
           [ 0.04 ,  0.018,  0.048,  0.057]])
    
    # Get absolute values
    In [11]: np.abs(a[:,1:] - dfB.values.ravel()) 
    Out[11]: 
    array([[ 0.92 ,  0.802,  0.642,  0.523],
           [ 0.02 ,  0.042,  0.022,  0.013],
           [ 0.02 ,  0.042,  0.012,  0.003],
           [ 0.   ,  0.022,  0.008,  0.017],
           [ 0.02 ,  0.002,  0.028,  0.037],
           [ 0.04 ,  0.018,  0.048,  0.057]])
    
    # Look for argmin along each col
    In [14]: idx = np.abs(a[:,1:] - dfB.values.ravel()).argmin(axis=0) 
    
    In [17]: idx
    Out[17]: array([3, 4, 3, 2])
    
    # First col from a
    In [15]: a[:,0] 
    Out[15]: array([ 0.,  1.,  2.,  3.,  4.,  5.])
    
    # Index into first col with those indices to select the desired output values
    In [16]: a[idx,0] 
    Out[16]: array([ 3.,  4.,  3.,  2.])
    

    【讨论】:

    • 嗯,可能主要是时间上的不同,因为NaN处理...你觉得呢?
    • @jezrael 我想这正是使用数组更快的方式,我猜? Nan 处理可以通过np.nanargmin() 解决。
    • @jezrael 如果你碰巧知道,pandas 是否使用broadcasting 进行这些减法?
    • 谢谢。我收到一个错误: ValueError: 操作数无法与形状 (51,1) (20,52) 一起广播。我使用的数据框有问题吗?
    • @BioProg 啊!我认为您需要使用:np.abs(dfA.values[:,1:] - dfB.values).argmin(0) 而不是从dfA 跳过第一列。看看?
    猜你喜欢
    • 2018-02-13
    • 2020-03-09
    • 1970-01-01
    • 1970-01-01
    • 2021-05-16
    • 2017-12-26
    • 2013-09-29
    • 2019-12-10
    • 1970-01-01
    相关资源
    最近更新 更多