Numpy 使用itertools.groupby()和recarray进行频率计数

Numpy 使用itertools.groupby()和recarray进行频率计数,numpy,itertools,recarray,Numpy,Itertools,Recarray,代码是这样的: >>>data = pd.DataFrame({'P': ['p1', 'p1', 'p2'], 'Q': ['q1', 'q2', 'q1'], 'R': ['r1', 'r1', 'r2']}) >>>data P Q R 0 p1 q1 r1 1 p1 q2 r1 2 p2 q1 r2 >>>data.group

代码是这样的:

>>>data = pd.DataFrame({'P': ['p1', 'p1', 'p2'],
                        'Q': ['q1', 'q2', 'q1'],
                        'R': ['r1', 'r1', 'r2']})

>>>data

  P  Q  R
0 p1 q1 r1
1 p1 q2 r1
2 p2 q1 r2

>>>data.groupby(['R'] + ['P','Q']).size().unstack(['P','Q'])
重新编制索引并填充NA0后,会得出以下结果:

P  p1      p2
Q  q1  q2  q1  q2
R
r1  1   1   0   0
r2  0   0   1   0
我想对recarray执行同样的操作,因此我导入了itertools并尝试了以下操作:

>>>data = np.array([('p1', 'p1', 'p2'), ('q1', 'q2', 'q1'), ('r1', 'r1', 'r2')], 
                     dtype=[('P',object),('Q',object),('R',object)]).view(np.recarray)

>>>groupby(data,key = (['R']+['P','Q'])).size().unstack(['P','Q'])

它不起作用。如何在不使用pandas的情况下获得类似的结果?

让我们远离花哨的重新排列和对象类型。它没有给我们买任何东西

数据可以是字符串的简单二维数组:

In [711]: data = np.array([('p1', 'p1', 'p2'), ('q1', 'q2', 'q1'), ('r1', 'r1', 'r2')])
In [712]: data
Out[712]: 
array([['p1', 'p1', 'p2'],
       ['q1', 'q2', 'q1'],
       ['r1', 'r1', 'r2']], 
      dtype='<U2')
intertools.group设计用于处理列表。它可以对数组进行操作,因为它可以对数组进行迭代

解释如何将这些字符串分组

熊猫群的表达方式并非一目了然

如果我只是将数据数组展平,我可以将顺序值分组并计数:

In [726]: data.ravel()
Out[726]: 
array(['p1', 'p1', 'p2', 'q1', 'q2', 'q1', 'r1', 'r1', 'r2'], 
      dtype='<U2')
In [727]: g=itertools.groupby(data.ravel())
In [728]: [(k,list(v)) for k,v in g]
Out[728]: 
[('p1', ['p1', 'p1']),
 ('p2', ['p2']),
 ('q1', ['q1']),
 ('q2', ['q2']),
 ('q1', ['q1']),
 ('r1', ['r1', 'r1']),
 ('r2', ['r2'])]
In [729]: g=itertools.groupby(data.ravel())
In [730]: [(k,len(list(v))) for k,v in g]
Out[730]: [('p1', 2), ('p2', 1), ('q1', 1), ('q2', 1), ('q1', 1), ('r1', 2), ('r2', 1)]
这也适用于数据的对象重新排列版本

哎呀,我误解了你对行的描述。即使重读你最后的评论,我也不明白你想要什么。这听起来根本不像是itertools.groupby的问题。我以为你在数像“r1”和“q2”这样的字符串。显然情况并非如此

====================

好的,更专注地尝试重新创建熊猫表

使用itertools.product生成这6个字符串的8个组合:

In [847]: pos = list(product(['r1','r2'],['p1','p2'],['q1','q2']))
In [848]: pos
Out[848]: 
[('r1', 'p1', 'q1'),
 ('r1', 'p1', 'q2'),
 ('r1', 'p2', 'q1'),
 ('r1', 'p2', 'q2'),
 ('r2', 'p1', 'q1'),
 ('r2', 'p1', 'q2'),
 ('r2', 'p2', 'q1'),
 ('r2', 'p2', 'q2')]
将数据帧转换为列表列表:

In [713]: data.tolist()
Out[713]: [['p1', 'p1', 'p2'], ['q1', 'q2', 'q1'], ['r1', 'r1', 'r2']]
In [849]: val=data.values[:,[2,0,1]].tolist()
In [850]: val
Out[850]: [['r1', 'p1', 'q1'], ['r1', 'p1', 'q2'], ['r2', 'p2', 'q1']]
查找在VAL中找到的可能组合:

将“计数”返工为2x8 0/1阵列:

In [853]: np.array([[list(i) in val] for i in pos]).reshape(2,-1).astype(int)
Out[853]: 
array([[1, 1, 0, 0],
       [0, 0, 1, 0]])

对不起,有个打字错误。我已将'R':['q1','q2','q1']替换为'R':['r1','r1','r2']。分组是按行进行的。例如,有一行“p1 q1 r1”,它出现一次,因此在输出中有一个对应的行。输出显示所有可能出现的行组合。如果存在这些组合,则显示其频率;如果不存在,则显示为零。这里,“p1 q1 r2”不存在,因此有一个零对应于它。我试图在不使用熊猫的情况下获得类似的输出。此外,输入需要是对象数据类型的结构化数组@hpauljIt还不清楚你想要什么。这不是recarray或itertools.groupby问题。我所说的行是指数据帧中的行,即输出中的行。这就是我刚才提到的行——p1q1r1,p1q2r1和p2q1r2。我想要的只是一个类似于上面结果的输出,而不使用熊猫。itertools.groupby只是我尝试过的一种无法锻炼的东西。如果不清楚,我道歉。不过这仍然是一个很好的答案,我学到了一些新的东西。谢谢-@hpauljOK,我通过搜索这些字符串的8种可能组合,重新创建了您的2x4表。
In [852]: [[i, list(i) in val] for i in pos]
Out[852]: 
[[('r1', 'p1', 'q1'), True],
 [('r1', 'p1', 'q2'), True],
 [('r1', 'p2', 'q1'), False],
 [('r1', 'p2', 'q2'), False],
 [('r2', 'p1', 'q1'), False],
 [('r2', 'p1', 'q2'), False],
 [('r2', 'p2', 'q1'), True],
 [('r2', 'p2', 'q2'), False]]
In [853]: np.array([[list(i) in val] for i in pos]).reshape(2,-1).astype(int)
Out[853]: 
array([[1, 1, 0, 0],
       [0, 0, 1, 0]])