[英]Itertools: selecting in pandas based on previous three rows, or previous elements in a list
希望为一整天困扰我的问题寻求帮助。 我有一个实验的数据,该实验通过屏幕要求受试者按键盘上的四个按钮之一('m','x','n','z')进行1600次试验。 在偶数试验中,按下按钮遵循随机选择的模式(例如mnzxmnzxmnzx),但在奇数试验中,按下按钮是随机选择的。 我获得的数据集仅包含受试者在哪个试验中按下的键。 我需要找出:
(1)主体的模式是什么。 (我尝试过此操作,因为该模式重复出现)
def find_pattern(df):
'''find the pattern for this subject'''
criterion = df['trial'].isin([1, 3, 5, 7])
the_pattern = df[criterion].circle_key.tolist()
return df
df = df.groupby('sid').apply(find_pattern)
(2)找出此主题模式的可能组合是什么(即,如果我按“ m”,则下一个模式元素将为“ x”)
为此,我尝试了一堆不同的itertools,但没有一个完全符合我的需要。 我想基本上列出:
['m', 'x', 'z', 'n']
对于进入(1)的每个对象,并进行两个IN ORDER的所有可能组合。 因此,这将是:
[('m', 'x'), ('x', 'z'), ('z', 'n'), ('n', 'm')]
并且没有其他可能性。 然后,我想创建一个列,该列在最近三个试验(包括当前的试验)中构成一个三联体,如下面的triplet
所示。 我觉得必须有某种滚动窗口,或者选择最后三个试验的简单方法。 我已经尝试了各种错误的方法-我似乎无法弄清楚如何引用数据帧中的“当前”行(不使用for
列表)...
我需要这些值,因为我需要比较triplet
的第一个和最后一个元素是否是可能的组合之一( possible_comb
)。 (因此,对于试验3,答案将为TRUE,而对于试验4,答案将为FALSE)。
任何帮助将不胜感激。 我当前的数据如下所示:
trial sid key
1 1 'm'
2 1 'm'
3 1 'x'
4 1 'n'
5 1 'x'
6 1 'x'
7 1 'n'
1 2 'm'
2 2 'm'
... ...
我希望它看起来像这样:
trial sid key pattern possible_comb triplet
1 1 'm' ['m', 'x', 'x', 'n'] [('m','x'), ('x','x'), ('x','n'), ('n', 'm')] NaN
2 1 'm' ['m', 'x', 'x', 'n'] [('m','x'), ('x','x'), ('x','n'), ('n', 'm')] NaN
3 1 'x' ['m', 'x', 'x', 'n'] [('m','x'), ('x','x'), ('x','n'), ('n', 'm')] ['m', 'm', 'x']
4 1 'n' ['m', 'x', 'x', 'n'] [('m','x'), ('x','x'), ('x','n'), ('n', 'm')] ['m', 'x', 'n']
5 1 'x' ['m', 'x', 'x', 'n'] [('m','x'), ('x','x'), ('x','n'), ('n', 'm')] ['x', 'n', 'x']
6 1 'x' ['m', 'x', 'x', 'n'] [('m','x'), ('x','x'), ('x','n'), ('n', 'm')] ['n', 'x', 'x']
7 1 'n' ['m', 'x', 'x', 'n'] [('m','x'), ('x','x'), ('x','n'), ('n', 'm')] ['x', 'x', 'n']
1 2 'n' ['n', 'x', 'm', 'n'] [('m','x'), ('x','x'), ('x','n'), ('n', 'm')] NaN
2 2 'm' ['n', 'x', 'm', 'n'] [('m','x'), ('x','x'), ('x','n'), ('n', 'm')] NaN
... ...
要获得“模式”,您只需要对主题ID进行分组,并获取其他所有元素。 可以这样做:
>>> d.groupby('sid')['key'].apply(lambda c: list(c[::2]))
sid
1 ['m', 'x', 'x', 'n']
(由于您仅包含了来自主题2的部分数据,因此删节了您的示例,只包含了一个主题,这太短了,因此没有这样的“模式”。这就是主题1的模式。)
如果要在对应主题的原始DataFrame的每一行中复制该数据,请使用map
来获取每个主题ID的模式:
>>> d['pattern'] = d.sid.map(d.groupby('sid')['key'].apply(lambda c: list(c[::2])))
>>> d
trial sid key pattern
0 1 1 'm' ['m', 'x', 'x', 'n']
1 2 1 'm' ['m', 'x', 'x', 'n']
2 3 1 'x' ['m', 'x', 'x', 'n']
3 4 1 'n' ['m', 'x', 'x', 'n']
4 5 1 'x' ['m', 'x', 'x', 'n']
5 6 1 'x' ['m', 'x', 'x', 'n']
6 7 1 'n' ['m', 'x', 'x', 'n']
要获得顺序组合,只需将第一个元素添加到末尾(以使序列“循环”),然后通过使用具有以下功能的两个元素的子列表来提取组合:
def getCombs(pattern):
pattern = pattern + [pattern[0]]
return [pattern[ix:ix+2] for ix in xrange(len(pattern)-1)]
然后,您可以将模式放入DataFrame中:
>>> d['combs'] = d.pattern.map(getCombs)
>>> d.combs
0 [['m', 'x'], ['x', 'x'], ['x', 'n'], ['n', 'm']]
1 [['m', 'x'], ['x', 'x'], ['x', 'n'], ['n', 'm']]
2 [['m', 'x'], ['x', 'x'], ['x', 'n'], ['n', 'm']]
3 [['m', 'x'], ['x', 'x'], ['x', 'n'], ['n', 'm']]
4 [['m', 'x'], ['x', 'x'], ['x', 'n'], ['n', 'm']]
5 [['m', 'x'], ['x', 'x'], ['x', 'n'], ['n', 'm']]
6 [['m', 'x'], ['x', 'x'], ['x', 'n'], ['n', 'm']]
Name: combs, dtype: object
(我在这里仅显示“梳子”列,因为包括所有列都使其太宽而无法舒适地显示。)
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.