我有一个数据框架,结构如下:
df = pd.DataFrame({'TIME':list('12121212'),'NAME':list('aabbccdd'), 'CLASS':list("AAAABBBB"),
'GRADE':[4,5,4,5,4,5,4,5]}, columns = ['TIME', 'NAME', 'CLASS','GRADE'])
print(df):
TIME NAME CLASS GRADE
0 1 a A 4
1 2 a A 5
2 1 b A 4
3 2 b A 5
4 1 c B 4
5 2 c B 5
6 1 d B 4
7 2 d B 5
我需要做的是根据变量CLASS
将上述数据框拆分为多个数据框,将数据框从长转换为宽(这样我们就有NAMES
作为列,GRADE
作为数据矩阵中的主要条目),然后在较小的CLASS
数据框上迭代其他函数。如果我按照这里的建议创建一个dict
对象,我将得到:
d = dict(tuple(df.groupby('CLASS')))
print(d):
{'A': TIME NAME CLASS GRADE
0 1 a A 4
1 2 a A 5
2 1 b A 4
3 2 b A 5, 'B': TIME NAME CLASS GRADE
4 1 c B 4
5 2 c B 5
6 1 d B 4
7 2 d B 5}
为了将数据帧从长转换为宽,我使用了pandas
中的pivot_table
函数:
for names, classes in d.items():
newdata=df.pivot_table(index="TIME", columns="NAME", values="GRADE")
print(newdata):
NAME a b c d
TIME
1 4 4 4 4
2 5 5 5 5
到目前为止一切顺利。然而,一旦我获得newdata
数据框,我就无法访问在d
中创建的较小的数据框,因为变量CLASS
现在从数据框中丢失了(应该是这样)。假设我需要在两个较小的子帧CLASS==A
和CLASS==B
上迭代一个函数。如果我不能使用列CLASS
定义数据集结构,我如何能够使用for循环来做到这一点?
尝试使用groupby
+apply
来保存组名:
(df.groupby('CLASS')
.apply(lambda d: d.pivot_table(index="TIME", columns="NAME", values="GRADE"))
)
输出:
a b c d
CLASS TIME
A 1 4.0 4.0 NaN NaN
2 5.0 5.0 NaN NaN
B 1 NaN NaN 4.0 4.0
2 NaN NaN 5.0 5.0
另一种可能,循环遍历组,保持CLASS为列:
for group_name, group_df in df.groupby('CLASS', as_index=False):
print(f'working on group {group_name}')
print(group_df)
输出:
working on group A
TIME NAME CLASS GRADE
0 1 a A 4
1 2 a A 5
2 1 b A 4
3 2 b A 5
working on group B
TIME NAME CLASS GRADE
4 1 c B 4
5 2 c B 5
6 1 d B 4
7 2 d B 5