使用pandas转换为长格式面板数据

3

我有一个数据框,其中每行代表时间,每列代表个体。我希望将其高效地转换为pandas中的长格式面板数据格式,因为数据框相当大。我希望避免循环。以下是一个示例:给定以下数据框:

      id    1    2
date              
20150520  3.0  4.0
20150521  5.0  6.0

应该被转化为:

date        id        value
20150520    1         3.0
20150520    2         4.0
20150520    1         5.0
20150520    2         6.0

由于数据量很大,速度对我而言非常重要。如果需要取舍,我更喜欢速度而不是优雅。虽然我怀疑是否缺少了一个相当简单的函数,但 pandas 应该能够处理它。有什么建议吗?

3个回答

3

我认为你需要使用stackreset_index函数:

print (df)
            1    2
date              
20150520  3.0  4.0
20150521  5.0  6.0

df = df.stack().reset_index()
df.columns = ['date','id','value']
print (df)
       date id  value
0  20150520  1    3.0
1  20150520  2    4.0
2  20150521  1    5.0
3  20150521  2    6.0

print (df)
id          1    2
date              
20150520  3.0  4.0
20150521  5.0  6.0

df = df.stack().reset_index(name='value')
print (df)
       date id  value
0  20150520  1    3.0
1  20150520  2    4.0
2  20150521  1    5.0
3  20150521  2    6.0

这既正确又比其他提出的解决方案更快。 - splinter

2
使用 melt
pd.melt(df.reset_index(),
        id_vars='date',
        value_vars=['1', '2'],
        var_name='Id')

在此输入图片描述


编辑:
因为楼主想要快速;-)

def pir(df):
    dv = df.values
    iv = df.index.values
    cv = df.columns.values
    rc, cc = df.shape
    return pd.DataFrame(
        dict(value=dv.flatten(),
             id=np.tile(cv, rc)),
        np.repeat(iv, cc))

感谢@piRSSquared,这确实可行,但是被采纳的解决方案更快1.25倍。 - splinter
@jezrael的回答是我推荐的。有时候我会发布另一种解决方案,因为它可能仍然对其他人或甚至你有用。我发现其他帖子的解决方案非常宝贵。pandas/numpy通常有许多解决方案,其中一些在某些情况下更快,在其他情况下则更慢。 - piRSquared
非常感谢,这个替代方案很有道理,我会记在心里的。 - splinter
@splinter 我已经用更快的解决方案更新了帖子。请记住,如果您在问题中说明速度/效率是您的目标,您几乎总会得到不同风格的响应。 - piRSquared

1
你要找的函数是:
df.reset_index()

您可以使用以下代码重命名列:

you can then rename your columns using

df.columns = ['date', 'id', 'value']

那样行不通。显然,我还需要上面提到的堆栈函数。谢谢。 - splinter

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