Python pandas:为DataFrame添加分组首行及对应月份航班数列报错解决
解决DataFrame添加列时的索引不匹配错误&实现机场对月度航班数统计
嘿,我来帮你搞定这个问题!先拆解一下你的需求和遇到的问题:你想要给每个机场对(出发+到达)添加2月、8月的航班数量列,同时尝试添加分组首行数据时碰到了索引不匹配的错误,咱们一步步来解决。
首先分析错误原因
你写的这段代码:
df = df.assign(newcol = lambda x: df.groupby(['APT_ORG_CODE','APT_ORG','APT_DES','APT_DES_CODE'],as_index=False)['Nb_flights'].first())
问题出在groupby(...).first()——它返回的是分组后的首行数据组成的小DataFrame(你的数据里是3行,对应3个机场对),但原DataFrame有6行,两者的索引长度不匹配,所以插入时就会抛出incompatible index of inserted column with frame index错误。
要给原DataFrame的每一行都添上对应分组的首行数据,得用transform('first')而不是first(),因为transform会把分组结果广播到组内所有行,保持和原DataFrame相同的长度。
解决方案一:添加2月、8月航班数量列
我们可以用pivot把月度数据转成列,再和原DataFrame合并,这样就能得到每个机场对的2月、8月航班数:
import pandas as pd # 先创建原DataFrame df = pd.DataFrame(data={ 'APT_ORG_CODE':['AAL','AAL','AAL','AAL','ZYI','ZYI'], 'APT_ORG':['Aalborg Airport','Aalborg Airport','Aalborg Airport','Aalborg Airport','Zunyi','Zunyi'], 'APT_DES':['Amsterdam','Amsterdam','Copenhagen Kastrup Apt','Copenhagen Kastrup Apt','Zhuhai','Zhuhai'], 'APT_DES_CODE':['AMS','AMS','CPH','CPH','ZUH','ZUH'], 'Month':[2,8,2,8,2,8], 'Nb_flights':[85,60,209,213,4,13] }) # 生成每个机场对的月度航班数透视表 pivot_df = df.pivot( index=['APT_ORG_CODE','APT_ORG','APT_DES','APT_DES_CODE'], columns='Month', values='Nb_flights' ).rename(columns={2: 'Feb_flights', 8: 'Aug_flights'}).reset_index() # 和原DataFrame合并,给每一行添上对应机场对的2月、8月数据 df = df.merge(pivot_df, on=['APT_ORG_CODE','APT_ORG','APT_DES','APT_DES_CODE'], how='left')
运行后,df会新增Feb_flights和Aug_flights两列,每个机场对的两行都会对应正确的月度航班数。
解决方案二:添加分组首行数据列
用transform来实现,它会返回和原DataFrame长度一致的Series,完美匹配索引:
方法1:仅添加分组首行的航班数
df['group_first_flight'] = df.groupby(['APT_ORG_CODE','APT_ORG','APT_DES','APT_DES_CODE'])['Nb_flights'].transform('first')
方法2:添加分组首行的任意列数据(比如出发机场名称)
df['group_first_org'] = df.groupby(['APT_ORG_CODE','APT_ORG','APT_DES','APT_DES_CODE'])['APT_ORG'].transform(lambda x: x.iloc[0])
如果想要把分组首行的所有数据都添加上,可以对整个分组用first()后合并:
# 生成分组首行的完整数据,再合并到原df group_first_df = df.groupby(['APT_ORG_CODE','APT_ORG','APT_DES','APT_DES_CODE']).first().add_prefix('group_first_').reset_index() df = df.merge(group_first_df, on=['APT_ORG_CODE','APT_ORG','APT_DES','APT_DES_CODE'], how='left')
最终效果示例
处理后的df会是这样的(截取部分列):
| APT_ORG_CODE | APT_ORG | APT_DES | Month | Nb_flights | Feb_flights | Aug_flights | group_first_flight |
|---|---|---|---|---|---|---|---|
| AAL | Aalborg Airport | Amsterdam | 2 | 85 | 85 | 60 | 85 |
| AAL | Aalborg Airport | Amsterdam | 8 | 60 | 85 | 60 | 85 |
| AAL | Aalborg Airport | Copenhagen Kastrup Apt | 2 | 209 | 209 | 213 | 209 |
内容的提问来源于stack exchange,提问作者Lucas Snow
相关产品推荐
相关产品推荐

