在Pandas数据框中反转最佳方法
我有一些数据,在周末、公共假期等时候缺少值。
datadate | id | Value
-----------------------
1999-12-31 | 01 | 1.0
1999-12-31 | 02 | 0.5
1999-12-31 | 03 | 3.2
2000-01-04 | 01 | 1.0
2000-01-04 | 02 | 0.7
2000-01-04 | 03 | 3.2
我想把这些缺失的日期的值复制过来。所以,我把数据进行了透视,重新索引,然后把值往下复制。
datadate | 01 | 02 | 03
----------------------------
1999-12-31 | 1.0 | 0.5 | 3.2
2000-01-01 | 1.0 | 0.5 | 3.2
2000-01-02 | 1.0 | 0.5 | 3.2
2000-01-03 | 1.0 | 0.5 | 3.2
2000-01-04 | 1.0 | 0.7 | 3.2
现在我想把数据恢复到最初的样子。我试过用 pd.melt()
和 df.unstack()
,但结果是列数比我想要的多,而且从结果中构建一个新的数据框花了很长时间。
有没有更好的方法来把数据恢复成原来的样子?
2 个回答
1
你可以通过在 melt 函数中设置正确的属性来实现这个功能,像这样:
datedate 01 02 03
0 1999-12-31 1 0.5 3.2
1 2000-01-01 1 0.5 3.2
2 2000-01-02 1 0.5 3.2
3 2000-01-03 1 0.5 3.2
4 2000-01-04 1 0.5 3.2
df_unpivoted = df.melt(id_vars=['datedate'], var_name='id', value_name='value')
datedate id value
0 1999-12-31 01 1.0
1 2000-01-01 01 1.0
2 2000-01-02 01 1.0
3 2000-01-03 01 1.0
4 2000-01-04 01 1.0
5 1999-12-31 02 0.5
6 2000-01-01 02 0.5
7 2000-01-02 02 0.5
8 2000-01-03 02 0.5
9 2000-01-04 02 0.5
10 1999-12-31 03 3.2
11 2000-01-01 03 3.2
12 2000-01-02 03 3.2
13 2000-01-03 03 3.2
14 2000-01-04 03 3.2
在下面的链接中,你可以找到一个更详细的例子:
https://dfrieds.com/data-analysis/melt-unpivot-python-pandas
3
有一个叫做 pandas.pivot_table
的函数,如果你把 datadate
和 id
定义为索引的话,就可以对数据表进行 unstack
操作。
这样写:
from io import StringIO
import pandas
datatable = StringIO("""\
datadate | id | Value
1999-12-31 | 01 | 1.0
1999-12-31 | 02 | 0.5
1999-12-31 | 03 | 3.2
2000-01-04 | 01 | 1.0
2000-01-04 | 02 | 0.7
2000-01-04 | 03 | 3.2""")
fullindex = pandas.DatetimeIndex(freq='1D', start='1999-12-31', end='2000-01-06')
df = (
pandas.read_table(datatable, sep='\s+\|\s+', parse_dates=['datadate'])
.set_index(['datadate', 'id'])
.unstack(level='id')
.reindex(fullindex)
.fillna(method='ffill')
.stack()
.reset_index()
.rename(columns={'level_0': 'date'})
)
print(df)
这样我就得到了:
date id Value
0 1999-12-31 1 1.0
1 1999-12-31 2 0.5
2 1999-12-31 3 3.2
3 2000-01-01 1 1.0
4 2000-01-01 2 0.5
5 2000-01-01 3 3.2
6 2000-01-02 1 1.0
7 2000-01-02 2 0.5
8 2000-01-02 3 3.2
9 2000-01-03 1 1.0
10 2000-01-03 2 0.5
11 2000-01-03 3 3.2
12 2000-01-04 1 1.0
13 2000-01-04 2 0.7
14 2000-01-04 3 3.2
15 2000-01-05 1 1.0
16 2000-01-05 2 0.7
17 2000-01-05 3 3.2
18 2000-01-06 1 1.0
19 2000-01-06 2 0.7
20 2000-01-06 3 3.2
(我喜欢把操作连在一起写)