首页 文章

查找匹配条件的数据帧中的第一行

提问于
浏览
3

我有两个数据帧 . 我的第一个数据框有两列,我想用它来创建一个条件并从第二个数据帧返回一个值 .

df1 = (['a', 'a', 'b', 'c'], [0.4, 0.9, 0.1, 0.6])

df2 = (['a', 'a', 'b', 'b', 'c', 'c'], [0.2, 0.6, 0.3, 0.8, 0.1, 0.4], 
              [500, 200, 900, 400, 250, 800])

对于df1中的每一行,我想通过两列数据查找df2 . 第一个条件是将df1中的字母与df2匹配 . 第二个条件是在df2中查找第一个数字行,其中数字大于df1 . 如果没有更大的数字,请取df2中与该字母匹配的第一行 .

我的目标输出是:

  • df1 row [0] = 500#'a'匹配'a'&0.4大于0.2

  • df1 row [1] = 200#'a'匹配'a'&0.9大于0.6

  • df1 row [2] = 900#'b'匹配'b'&没有行大于0.1所以返回第'b'行

  • df1 row [3] = 800#'c'匹配'c'&0.6大于0.4

对于我的问题任何不良格式的道歉,请提供有关发布的任何建议(这是我的第一个) .

非常感谢!

2 回答

  • 1

    我认为更好的是避免迭代 .
    我将 df1df2 中的数据合并为 a 列 . 输出的行数比原始 df1 多两倍 . 然后条件由np.where应用,输出转换为整数 . 系列 s 包含输出,每个奇数值 . (因为合并了 df1 中的一行和 df2 中的两行)

    #   a    b
    #0  a  0.4
    #1  a  0.9
    #2  b  0.1
    #3  c  0.6
    
    #   a    c    d
    #0  a  0.2  500
    #1  a  0.6  200
    #2  b  0.3  900
    #3  b  0.8  400
    #4  c  0.1  250
    #5  c  0.4  800  
    
    #merged data - intersection df1 and df2 by column a
    df = pd.merge(df1, df2, on=['a'], how='inner')
    #apply condition
    s = np.where(df['c']< df['b'], df['d'], df['d'].shift(1)).astype('int')
    #odd values
    s = s[1::2]
    #[500 200 900 800]
    
    #if need add data do df1 as column e
    #df1['e'] = pd.Series(s, index=df1.index)
    

    迭代解决方案(Delforge):

    100 loops, best of 3: 4.67 ms per loop
    

    合并解决方案(我):

    100 loops, best of 3: 1.93 ms per loop
    
  • 3

    您可以迭代df1并根据列0字母和大于两列之间的比较进行选择1.假设您的列1值是升序,如果所选数据帧不为空,则存储列2的最后一个值 . 如果为空获取与列0选择匹配的df2 col 2的第一个值 .

    这是一个例子,我将结果存储在一个字典中 .

    例:

    你的数据

    import pandas as pd
    
    df1 = pd.DataFrame(data = [['a', 'a', 'b', 'c'], [0.4, 0.9, 0.1, 0.6]]).transpose()
    
    df2 = pd.DataFrame(data = [['a', 'a', 'b', 'b', 'c', 'c'], [0.2, 0.6, 0.3, 0.8, 0.1, 0.4], [500, 200, 900, 400, 250, 800]]).transpose()
    

    迭代:

    results = {} # dictionnary to store results
    
    for i, row in df1.iterrows():
        select = df2[(df2[0] == row[0]) & (df2[1] < row[1])] # selection
    
        if not select.empty:
            results[i] = select[2].iloc[-1] # storing last value of column 2
        else:
            results[i] = df2[df2[0] == row[0]][2].iloc[0] # storing first value if no greater than match
    
    print results # {0: 500, 1: 200, 2: 900, 3: 800}
    

相关问题