Tengo dos marcos de datos, cada uno tiene las mismas columnas 1) la respuesta hecha por un participante 2) el tiempo de respuesta en segundos y milisegundos (s.ms). Por ejemplo,
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
También tengo un marco de datos que son las respuestas y tiempos 'correctos'. Por ejemplo,
correctData =
Key RT
0 v 2.25
1 w 4.34
2 v 5.61
3 v 20.30
Quiero indicar que hay una coincidencia tanto en la clave de respuesta Y el tiempo de respuesta dentro de - + 1 segundo. Por lo tanto, primero verifique que la clave de respuesta coincida, y si es así, compare la hora en que ocurrió esta respuesta. Si ocurrió dentro de 1s, se considera correcto. Tenga en cuenta que el sujeto puede haber respondido más veces de lo correcto. Entonces quiero comparar estas columnas sin importar el orden. Por ejemplo, observe que la sexta respuesta en el cuadro subjectData coincide con la tercera en el cuadro correctoData (dentro de un segundo). Debido a esto, la tercera entrada en la salida es VERDADERA, lo que indica que la tercera respuesta correcta coincidió.
Entonces el resultado final debería verse así
TRUE
FALSE
TRUE
TRUE
Observe que la salida tiene la misma longitud que el marco de datos correctData e indica qué respuestas correctas coinciden con el subjectData. Por lo tanto, indica que el sujeto lo entendió correctamente SI presionaron el botón correcto, dentro de un segundo del tiempo 'correcto' que figura en el marco de datos proporcionado. Tenga en cuenta que estos marcos de datos probablemente NO tendrán la misma longitud (el sujeto puede responder más o menos que el número 'correcto' de respuestas). Entonces 'unirse' puede no funcionar aquí.
¿Alguna idea sobre cómo hacer esto de manera más eficiente?
4 respuestas
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'])
Salida:
array([ True, False, True, True])
Yo usaría 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
1) Use DataFrame.eq para comparar la columna key
de ambos marcos de datos:
cond1=subjectData['Key'].eq(correctData['Key'])
2) luego verifique si está en el rango de + -1s
cond2=(subjectData['RT']<(correctData['RT']+1))&(subjectData['RT']>(correctData['RT']-1))
3) finalmente verifique qué filas cumplen ambas condiciones (con1,cond2
):
cond1&cond2
0 True
1 False
2 True
3 False
dtype: bool
A ver si esto funciona.
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
Preguntas relacionadas
Nuevas preguntas
python
Python es un lenguaje de programación multipropósito, de tipificación dinámica y de múltiples paradigmas. Está diseñado para ser rápido de aprender, comprender y usar, y hacer cumplir una sintaxis limpia y uniforme. Tenga en cuenta que Python 2 está oficialmente fuera de soporte a partir del 01-01-2020. Aún así, para preguntas de Python específicas de la versión, agregue la etiqueta [python-2.7] o [python-3.x]. Cuando utilice una variante de Python (por ejemplo, Jython, PyPy) o una biblioteca (por ejemplo, Pandas y NumPy), inclúyala en las etiquetas.