转换 Pandas 数据框的最佳方法是什么?

5

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

 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(),但最终得到的列比我想要的多,并且从结果构建新的数据框需要很长时间。

有更好的方法来转换数据吗?


"more columns than I want" -- 这是什么意思?你应该为id中的每个唯一值都有一列。你实际想要什么? - Paul H
2个回答

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

(我喜欢链式编程)


我认为OP想要另一种方式?从pv到df。我认为你可以用melt来实现,但看起来有点麻烦! - Andy Hayden
我认为需要进行取消堆叠、重新索引和填充缺失值的操作。我错过了填补缺失日期的部分。我认为我们只是有一个太小的示例数据集。 - Paul H
谁不喜欢链式编程!顺便说一下,我更喜欢在每行使用括号而不是反斜杠(我讨厌那些东西!:p)。 - Andy Hayden

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


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