假设我有一个像这样的列表的Python dict:
{'Grp': ['2' , '6' , '6' , '5' , '5' , '6' , '6' , '7' , '7' , '6'],
'Nums': ['6.20', '6.30', '6.80', '6.45', '6.55', '6.35', '6.37', '6.36', '6.78', '6.33']}
Run Code Online (Sandbox Code Playgroud)
我可以使用itertools.groupby轻松地对数字和组密钥进行分组:
from itertools import groupby
for k, l in groupby(zip(di['Grp'], di['Nums']), key=lambda t: t[0]):
print k, [t[1] for t in l]
Run Code Online (Sandbox Code Playgroud)
打印:
2 ['6.20']
6 ['6.30', '6.80'] # one field, key=6
5 ['6.45', '6.55']
6 ['6.35', '6.37'] # second
7 ['6.36', '6.78']
6 ['6.33'] # third
Run Code Online (Sandbox Code Playgroud)
请注意,6密钥分为三个单独的组或字段.
现在假设我的dict有相同的Pandas DataFrame(相同的数据,相同的列表顺序和相同的键):
Grp Nums
0 2 6.20
1 6 6.30
2 6 6.80
3 5 6.45
4 5 6.55
5 6 6.35
6 6 6.37
7 7 6.36
8 7 6.78
9 6 6.33
Run Code Online (Sandbox Code Playgroud)
如果我使用Pandas的groupby,我没有看到如何逐组迭代.相反,Pandas按键值分组:
for e in df.groupby('Grp'):
print e
Run Code Online (Sandbox Code Playgroud)
打印:
('2', Grp Nums
0 2 6.20)
('5', Grp Nums
3 5 6.45
4 5 6.55)
('6', Grp Nums
1 6 6.30
2 6 6.80 # df['Grp'][1:2] first field
5 6 6.35 # df['Grp'][5:6] second field
6 6 6.37
9 6 6.33) # df['Grp'][9] third field
('7', Grp Nums
7 7 6.36
8 7 6.78)
Run Code Online (Sandbox Code Playgroud)
注意,6组密钥是捆在一起的; 不是单独的团体.
我的问题:是否有一种相同的方式来使用Pandas的groupby,以便6,例如,将以与Python相同的方式分成三组groupby?
我试过这个:
>>> df.reset_index().groupby('Grp')['index'].apply(lambda x: np.array(x))
Grp
2 [0]
5 [3, 4]
6 [1, 2, 5, 6, 9] # I *could* do a second groupby on this...
7 [7, 8]
Name: index, dtype: object
Run Code Online (Sandbox Code Playgroud)
但它仍然按整体Grp键分组,我需要做第二个nd.array组来分割每个键的子组.
Joe*_*ron 12
首先,您可以确定Grp列中的哪些元素与前一个元素不同,并获得累积总和以形成您需要的组:
In [9]:
diff_to_previous = df.Grp != df.Grp.shift(1)
diff_to_previous.cumsum()
Out[9]:
0 1
1 2
2 2
3 3
4 3
5 4
6 4
7 5
8 5
9 6
Run Code Online (Sandbox Code Playgroud)
所以你可以这样做
df.groupby(diff_to_previous.cumsum())
Run Code Online (Sandbox Code Playgroud)
获得所需的groupby对象
好吧,不要厚脸皮,但为什么不groupby通过使用iterrows在 DataFrame 上使用 Python呢?这就是它的用途:
>>> df
Grp Nums
0 2 6.20
1 6 6.30
2 6 6.80
3 5 6.45
4 5 6.55
5 6 6.35
6 6 6.37
7 7 6.36
8 7 6.78
9 6 6.33
>>> from itertools import groupby
>>> for k, l in groupby(df.iterrows(), key=lambda row: row[1]['Grp']):
print k, [t[1]['Nums'] for t in l]
Run Code Online (Sandbox Code Playgroud)
印刷:
2 ['6.20']
6 ['6.30', '6.80']
5 ['6.45', '6.55']
6 ['6.35', '6.37']
7 ['6.36', '6.78']
6 ['6.33']
Run Code Online (Sandbox Code Playgroud)
尝试让 Pandagroupby以您想要的方式行事,可能会要求很多堆叠的方法,以至于您将来重新阅读时将无法遵循它。