2014-07-14 108 views
6

我有两只大熊猫dataframes,一个相当大(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 
... ... ...   ...  ... 

的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 
... ... ... ... 

我想要做的就是在DFB每一行找到DFA行其中的值的X和Y列相等,并且在第一行,其中DFB的值[“TIME”]比DFA [“ONSET_TIME”]更大,此行返回DFA [“COLOR”]的值。

dfA代表显示器的刷新,其中X和Y是显示器上的项目坐标,并且对于每个不同的ONSET_TIME重复它们自己(每个ONSET_TIME值有108对协调对)。

会有多行,其中两个dataframes X和Y是相等的,但我需要的是时间太相匹配的。

我已经这样做了使用循环和if语句只是为了看看它可以做,但显然考虑到dataframes的大小这需要很长的时间。

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] 

回答

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 

的基本思想是合并这两个表格,这样你就可以在一张表格中共享时间。然后我筛选出最大(最接近你的dfB)时间的recs。如果您对此有任何疑问,请告知我。

+0

这真的很有帮助,谢谢,虽然我发现你最后的群组DF错过了原始DfB的一些值。 我试过了:filteredDF.sort('ONSET_TIME').groupby(['DfB_INDEX'],as_index = False).max() 这就给了我我正在寻找的值,据我所知。 –

0

使用merge() - 它就像JOIN在SQL - 你有第一部分完成。

d1 = '''  X  Y ONSET_TIME COLOUR 
    104 78   1083   6  
    172 78   1083  16 
    240 78   1083  15 
    308 78   1083   8 
    376 78   1083   8 
    444 78   1083  14 
    512 78   1083  14 
    308 78   3000  14 
    308 78   2000  14''' 


d2 = ''' TIME  X  Y 
     7 512 350 
    1722 512 214 
    1906 376 214 
    2095 376 146 
    2234 308 78 
    2406 172 146''' 

import pandas as pd 
from StringIO import StringIO 

dfA = pd.DataFrame.from_csv(StringIO(d1), sep='\s+', index_col=None) 
#print dfA 

dfB = pd.DataFrame.from_csv(StringIO(d2), sep='\s+', index_col=None) 
#print dfB 

df1 = pd.merge(dfA, dfB, on=['X','Y']) 
print df1 

结果:

 X Y ONSET_TIME COLOUR TIME 
0 308 78  1083  8 2234 
1 308 78  3000  14 2234 
2 308 78  2000  14 2234 

然后你可以用它来过滤结果。

df2 = df1[ df1['ONSET_TIME'] < df1['TIME'] ] 
print df2 

结果:

 X Y ONSET_TIME COLOUR TIME 
0 308 78  1083  8 2234 
2 308 78  2000  14 2234 
+0

他也想时间会比onset_time更大。添加df = pd.merge(dfA,dfB,on = ['X','Y']); DF = DF [DF [ “ONSET_TIME”]> DF [ “TIME”]] – ZJS

+0

谢谢,我在同时做吧:)我一块做一块 - 测试 - 并添加回答。这样我学习'熊猫':) :) – furas

相关问题