如何将带有小时值和日期时间索引的宽格式转换为长格式?

2 投票
1 回答
859 浏览
提问于 2025-04-18 15:37

我正在从一个固定的SQL数据结构中获取数据,这些数据是以长格式存储的,现在我想把它转换成宽格式。

这里有个复杂的地方,每一行数据代表一个产品在一天内的值。这些值存储在表示一天中特定小时的列中。下面的例子显示了一个六小时的时间间隔。这意味着我们每天会在00:00、06:00、12:00和18:00存储四个值。这个数据框(DataFrame)看起来是这样的:

      id        date  0000  0600  1200  1800
 0  APPL  01.01.2014    12    15    17    19
 1  APPL  02.01.2014    21    23    25    27
 2  MSFT  01.01.2014     1     2     3     4
 3  MSFT  02.01.2014     5     6     7     8

我想要的宽格式数据框是:

                     APPL  MSFT
2014-01-01 00:00:00    12     1
2014-01-01 06:00:00    15     2
2014-01-01 12:00:00    17     3
2014-01-01 18:00:00    19     4
2014-01-02 00:00:00    21     5
2014-01-02 06:00:00    23     6
2014-01-02 12:00:00    25     7
2014-01-02 18:00:00    27     8

我尝试了多种组合,比如使用pivot、unstack和set_index来达到目标结构,但都没有成功。我离目标最近的是使用:

df = src.set_index(['date','id']).stack()

这段代码返回了:

date        id        
01.01.2014  APPL  0000    12
                  0600    15
                  1200    17
                  1800    19
02.01.2014  APPL  0000    21
                  0600    23
                  1200    25
                  1800    27
01.01.2014  MSFT  0000     1
                  0600     2
                  1200     3
                  1800     4
02.01.2014  MSFT  0000     5
                  0600     6
                  1200     7
                  1800     8

但现在我无法解决这个多重索引的问题。

任何帮助都非常感谢。

1 个回答

3
import pandas as pd
import io

text = """      id        date  0000  0600  1200  1800
 0  APPL  01.01.2014    12    15    17    19
 1  APPL  02.01.2014    21    23    25    27
 2  MSFT  01.01.2014     1     2     3     4
 3  MSFT  02.01.2014     5     6     7     8"""

df = pd.read_csv(io.BytesIO(text), delim_whitespace=True)
df = df.set_index(["id", "date"]).stack().unstack(0)

def f(key):
    date, hour = key
    time = "{} {}:{}:00".format(date, hour[:2], hour[2:])
    return pd.to_datetime(time, dayfirst=True)

df.index = df.index.map(f)
print df

输出结果:

id                   APPL  MSFT
2014-01-01 00:00:00    12     1
2014-01-01 06:00:00    15     2
2014-01-01 12:00:00    17     3
2014-01-01 18:00:00    19     4
2014-01-02 00:00:00    21     5
2014-01-02 06:00:00    23     6
2014-01-02 12:00:00    25     7
2014-01-02 18:00:00    27     8

撰写回答