基于列名在pandas数据框中进行堆叠

4

我有一个pandas数据框:

 ID   Year  Jan_salary  Jan_days  Feb_salary Feb_days Mar_salary Mar_days
  1   2016     4500        22         4200      18        4700       24
  2   2016     3800        23         3600      19        4400       23
  3   2016     5500        21         5200      17        5300       23

我希望将这个数据框转换为以下数据框:
ID     Year     month   salary   days
 1      2016      01     4500     22
 1      2016      02     4200     18
 1      2016      03     4700     24
 2      2016      01     3800     23
 2      2016      02     3600     19
 2      2016      03     4400     23
 3      2016      01     5500     21
 3      2016      02     5200     17
 3      2016      03     5300     23

我尝试使用 pandas.DataFrame.stack 但是没有得到预期的结果。 我正在使用 Python 2.7 请指导我如何重新塑造这个Pandas数据框架。 谢谢。


1
你是如何尝试使用“堆栈(stack)”的? - Jon Clements
2个回答

6
df = df.set_index(['ID', 'Year'])
df.columns = df.columns.str.split('_', expand=True).rename('month', level=0)
df = df.stack(0).reset_index()
md = dict(Jan='01', Feb='02', Mar='03')
df.month = df.month.map(md)


df[['ID', 'Year', 'month', 'salary', 'days']]

enter image description here


比我更好的解决方案,而且速度更快!+1。不过我还是会发布我的,哈哈。 - mechanical_meat
1
@Bernie,现在我充满了期待 :-) - piRSquared

1

我喜欢使用pd.melt,因此在这个冗长的方法中我使用了它:

ldf = pd.melt(df,id_vars=['ID','Year'],
              value_vars=['Jan_salary','Feb_salary','Mar_salary'],
              var_name='month',value_name='salary')
rdf = pd.melt(df,id_vars=['ID','Year'],
              value_vars=['Jan_days','Feb_days','Mar_days'],
              value_name='days')
rdf.drop(['ID','Year','variable'],inplace=True,axis=1)
cdf = pd.concat([ldf,rdf],axis=1)
cdf['month'] = cdf['month'].str.replace('_salary','')
import calendar
def mapper(month_abbr):
    # from https://dev59.com/W3A75IYBdhLWcg3wOGLS#3418092
    d = {v: str(k).zfill(2) for k,v in enumerate(calendar.month_abbr)}
    return d[month_abbr]
cdf['month'] = cdf['month'].apply(mapper)

结果:

>>> cdf
   ID  Year month  salary  days
0   1  2016    01    4500    22
1   2  2016    01    3800    23
2   3  2016    01    5500    21
3   1  2016    02    4200    18
4   2  2016    02    3600    19
5   3  2016    02    5200    17
6   1  2016    03    4700    24
7   2  2016    03    4400    23
8   3  2016    03    5300    23

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接