python输入长和宽_Python3 pandas处理长型与宽型数据

Python处理二维的dataframe数据主要依靠pandas包。这一点与R语言不同,R中处理dataframe的包是多面开花。不过现在这些处理函数慢慢有语法大一统的趋势,如tidyverse生态链。

在处理数据常常会遇到长宽数据互转,如从Wind数据库导出的公司财务数据。在Stata和R中已经有比较便捷的处理方法。

下面列示一下pandas包的处理方法。

首先,生成一份模拟数据。

import pandas as pd

import numpy as np

df=pd.DataFrame(np.random.rand(3,6),columns=['x', 'lev2015','roa2015', 'roa2016', 'lev2016','lev2017'])

df['stkcd']=['a1','a2','a3']

df

Out[1]:

x lev2015 roa2015 roa2016 lev2016 lev2017 stkcd

0 0.434583 0.352021 0.155295 0.307686 0.226555 0.718034 a1

1 0.440119 0.051882 0.667143 0.995478 0.114729 0.996174 a2

2 0.292902 0.516601 0.157647 0.066176 0.506407 0.968796 a3

然后开始从长转为宽。

df=df.melt(id_vars=['stkcd','x'],value_vars=['lev2015','roa2015', 'roa2016', 'lev2016','lev2017'],var_name='name',value_name='score')

df

Out[2]:

stkcd x name score

0 a1 0.434583 lev2015 0.352021

1 a2 0.440119 lev2015 0.051882

2 a3 0.292902 lev2015 0.516601

3 a1 0.434583 roa2015 0.155295

4 a2 0.440119 roa2015 0.667143

5 a3 0.292902 roa2015 0.157647

6 a1 0.434583 roa2016 0.307686

7 a2 0.440119 roa2016 0.995478

8 a3 0.292902 roa2016 0.066176

9 a1 0.434583 lev2016 0.226555

10 a2 0.440119 lev2016 0.114729

11 a3 0.292902 lev2016 0.506407

12 a1 0.434583 lev2017 0.718034

13 a2 0.440119 lev2017 0.996174

14 a3 0.292902 lev2017 0.968796

但是仔细一看,还需要再转一次。把name分割为两个变量。

df['year']=df['name'].str.slice(3,7)

df['name']=df['name'].str.slice(0,3)

df

Out[3]:

stkcd x name score year

0 a1 0.434583 lev 0.352021 2015

1 a2 0.440119 lev 0.051882 2015

2 a3 0.292902 lev 0.516601 2015

3 a1 0.434583 roa 0.155295 2015

4 a2 0.440119 roa 0.667143 2015

5 a3 0.292902 roa 0.157647 2015

6 a1 0.434583 roa 0.307686 2016

7 a2 0.440119 roa 0.995478 2016

8 a3 0.292902 roa 0.066176 2016

9 a1 0.434583 lev 0.226555 2016

10 a2 0.440119 lev 0.114729 2016

11 a3 0.292902 lev 0.506407 2016

12 a1 0.434583 lev 0.718034 2017

13 a2 0.440119 lev 0.996174 2017

14 a3 0.292902 lev 0.968796 2017

此时把name转回去即可(从变量的转成列变量的名)。这个就是我们想要的数据,不信你可以用df.to_csv('wide_long.csv')导出数据试试看。具体如下。

df=df.pivot_table(index=['stkcd','x','year'], columns='name', values='score')

df

Out[4]:

name lev roa

stkcd x year

a1 0.434583 2015 0.352021 0.155295

2016 0.226555 0.307686

2017 0.718034 NaN

a2 0.440119 2015 0.051882 0.667143

2016 0.114729 0.995478

2017 0.996174 NaN

a3 0.292902 2015 0.516601 0.157647

2016 0.506407 0.066176

2017 0.968796 NaN

不过呢,这个数据太难看了。进一步处理如下。

df=df.reset_index()

df

Out[5]:

name stkcd x year lev roa

0 a1 0.434583 2015 0.352021 0.155295

1 a1 0.434583 2016 0.226555 0.307686

2 a1 0.434583 2017 0.718034 NaN

3 a2 0.440119 2015 0.051882 0.667143

4 a2 0.440119 2016 0.114729 0.995478

5 a2 0.440119 2017 0.996174 NaN

6 a3 0.292902 2015 0.516601 0.157647

7 a3 0.292902 2016 0.506407 0.066176

8 a3 0.292902 2017 0.968796 NaN

最后附图(点击可以放大)。一般的长宽型都可以按照这个思路操作,只是会根据语言工具的差异略有调整。操作过程与版本信息示意图

问:为什么模拟那么丑的df?

答:有时候现实的df就很丑。

问:为什么这么写?麻烦,长。

答:通用,不惧df的美丑。

问:有更好的操作么?

答:靠你自动手?

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值