繁体   English   中英

Itertools:根据前三行或列表中的前一个元素选择大熊猫

[英]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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM