在Pandas数据框中反转最佳方法

5 投票
2 回答
3902 浏览
提问于 2025-04-20 22:08

我有一些数据,在周末、公共假期等时候缺少值。

 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 的函数,如果你把 datadateid 定义为索引的话,就可以对数据表进行 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

(我喜欢把操作连在一起写)

撰写回答