基于三列将一个Pandas数据帧中的行与另一个Pandas数据帧中的行匹配

Ale*_*M-R 10 python dataframe pandas

我有两个Pandas数据帧,一个非常大(30000多行),一个小很多(100多行).

dfA看起来像:

      X     Y    ONSET_TIME    COLOUR 
0   104    78          1083         6    
1   172    78          1083        16
2   240    78          1083        15 
3   308    78          1083         8
4   376    78          1083         8
5   444    78          1083        14
6   512    78          1083        14
... ...   ...           ...       ...
Run Code Online (Sandbox Code Playgroud)

dfB看起来像:

    TIME     X     Y
0      7   512   350 
1   1722   512   214 
2   1906   376   214 
3   2095   376   146 
4   2234   308    78 
5   2406   172   146
...  ...   ...   ...  
Run Code Online (Sandbox Code Playgroud)

我想要做的是为dfB中的每一行找到dfA中的行,其中X和Y列的值相等并且这是dfB ['TIME']的值大于dfA ['的第一行ONSET_TIME']并返回此行的dfA ['COLOR']值.

dfA表示显示器的刷新,其中X和Y是显示器上项目的坐标,因此对于每个不同的ONSET_TIME重复自己(对于ONSET_TIME的每个值,有108对坐标).

将有多行,其中两个数据帧中的X和Y相等,但我也需要与时间匹配的行.

我使用for循环和if语句只是为了看到它可以完成,但很明显,考虑到数据帧的大小,这需要很长时间.

for s in range(0, len(dfA)):
    for r in range(0, len(dfB)):
        if (dfB.iloc[r,1] == dfA.iloc[s,0]) and (dfB.iloc[r,2] == dfA.iloc[s,1]) and (dfA.iloc[s,2] <= dfB.iloc[r,0] < dfA.iloc[s+108,2]):
            return dfA.iloc[s,3]
Run Code Online (Sandbox Code Playgroud)

fly*_*all 5

有一种更有效的方法可以做到这一点,但这里有一个方法没有那些缓慢的for循环:

import pandas as pd

dfB = pd.DataFrame({'X':[1,2,3],'Y':[1,2,3], 'Time':[10,20,30]})
dfA = pd.DataFrame({'X':[1,1,2,2,2,3],'Y':[1,1,2,2,2,3], 'ONSET_TIME':[5,7,9,16,22,28],'COLOR': ['Red','Blue','Blue','red','Green','Orange']})

#create one single table
mergeDf = pd.merge(dfA, dfB, left_on = ['X','Y'], right_on = ['X','Y'])
#remove rows where time is less than onset time
filteredDf = mergeDf[mergeDf['ONSET_TIME'] < mergeDf['Time']]
#take min time (closest to onset time)
groupedDf = filteredDf.groupby(['X','Y']).max()

print filteredDf

 COLOR  ONSET_TIME  X  Y  Time
0     Red           5  1  1    10
1    Blue           7  1  1    10
2    Blue           9  2  2    20
3     red          16  2  2    20
5  Orange          28  3  3    30


print groupedDf

COLOR  ONSET_TIME  Time
X Y                          
1 1     Red           7    10
2 2     red          16    20
3 3  Orange          28    30
Run Code Online (Sandbox Code Playgroud)

基本思想是合并两个表,以便在一个表中将时间合并在一起.然后我过滤了最大的rec(最接近dfB上的时间).如果您对此有疑问,请与我们联系.