有条件地在python

时间:2019-09-30 20:03:06

标签: python pandas dataframe conditional-statements

我有两个数据帧,每个数据帧具有相同的列1)参与者做出的响应2)以秒和毫秒(s.ms)为单位的响应时间。 例如,

subjectData = 

Key     RT
0   v   2.20
1   v   4.34
2   v   5.51
3   v  10.39
4   w  12.50
5   v  14.62
6   v  20.22

我还有一个数据框,它是“正确”的响应和时间。例如,

correctData = 

Key     RT
0   v   2.25
1   w   4.34
2   v   5.61
3   v  20.30

我想指出-响应键和-+ 1秒内的响应时间都匹配。因此,首先检查响应键是否匹配,如果匹配,则比较此响应发生的时间。如果在1秒内发生,则认为是正确的。 请注意,受试者的反应次数可能超过正确的次数。因此,无论顺序如何,我都想比较这些列。例如,请注意上面的主题数据帧中的第6个响应与正确数据帧中的第3个响应(在一秒钟之内)匹配。因此,输出中的第三个条目为TRUE,表示匹配了第三个正确答案。

所以最终结果应该像这样

TRUE
FALSE
TRUE
TRUE

请注意,输出的长度与CorrectData数据帧的长度相同,并指示哪些正确答案与subjectData匹配。 因此,这表明受试者在提供的数据框中列出的“正确”时间内,只要按下正确的按钮,就可以正确按下按钮。请注意,这些数据框的长度很可能不一样(受试者的反应可能多于或少于“正确”的反应数)。因此,“加入”可能在这里不起作用。

关于如何最有效地执行此操作的任何想法?

4 个答案:

答案 0 :(得分:2)

subjectData = pd.DataFrame({'Key': ['v', 'v', 'v', 'v', 'w', 'v', 'v'],
                            'RT': [2.20, 4.34, 5.51, 10.39, 12.50, 14.62, 20.22]})

correctData = pd.DataFrame({'Key': ['v', 'w', 'v', 'v'],
                            'RT': [2.25, 4.34, 5.61, 20.30]})

df = subjectData.merge(correctData.reset_index(), on='Key', how='right', 
                       suffixes=['_subj', '_corr'])

df_timed = df[(df['RT_subj'] - df['RT_corr']).between(-1,1)]

correctData.index.isin(df_timed['index'])

输出:

array([ True, False,  True,  True])

答案 1 :(得分:1)

1)使用DataFrame.eq 比较两个数据框的key列:

cond1=subjectData['Key'].eq(correctData['Key'])

2),然后检查它是否在+ -1s

范围内
cond2=(subjectData['RT']<(correctData['RT']+1))&(subjectData['RT']>(correctData['RT']-1))

3)最后检查哪些行同时满足两个条件(con1,cond2):

cond1&cond2

0     True
1    False
2     True
3    False
dtype: bool

答案 2 :(得分:1)

我会使用numpy.isclose

(subjectData.Key == correctData.Key) & np.isclose(subjectData.RT, correctData.RT, atol=1)

0     True
1    False
2     True
3    False
Name: Key, dtype: bool

答案 3 :(得分:0)

查看是否可行。

cutoff_at_index = min(correctData.shape[0], subjectData.shape[0])
equal = subjectData.Key[:cutoff_at_index] == correctData.Key[:cutoff_at_index]
between = (subjectData.RT[:cutoff_at_index] >= correctData.RT[:cutoff_at_index]-1) \
          & (subjectData.RT[:cutoff_at_index] <=correctData.RT[:cutoff_at_index]+1)
equal & between