考虑这个玩具示例。我需要将每列向下移动一个*(它在数组中的位置)。所以是一种对角线的转变:
import numpy as np
import pandas as pd
df = pd.DataFrame(np.random.randint(1,10,(5,5)),columns=list("ABCDE"))
for i,k in enumerate(df):
df[k] = df[k].shift(i)
变换:
A B C D E
0 6 1 6 3 1
1 2 7 5 9 7
2 6 6 6 9 8
3 7 8 8 2 8
4 5 2 9 9 2
到
A B C D E
0 6 NaN NaN NaN NaN
1 2 1 NaN NaN NaN
2 6 7 6 NaN NaN
3 7 6 5 3 NaN
4 5 8 6 9 1
这就是我想要的。
但是对于具有分层索引的较大数据帧,此循环方法似乎不可行。事实上,我已经有一台ipython笔记本电脑已经运行了近一个小时,现在还没有结束。
这让我觉得必须有一种更容易的,可能是矢量化的方式......也许使用某种" apply"但是我不知道如何在每列需要时这样做作为其在阵列中的位置的函数向下移动。
答案 0 :(得分:2)
除非你真的有很多数据(几十千兆字节),否则转移不需要数小时。似乎花在重建指数上的时间。特别是对于分层索引,有可能在每次转换后重建复杂索引。如果你的桌子很大,这可能需要很长时间。
一种可能的方法(至少要隔离问题)只是将数据提取到np.array
(取.values
),移位它,然后重新创建DataFrame。在numpy
移位中,数据相当简单,例如:
for c in range(1, a.shape[1]):
a[c:,c] = a[:-c,c]
a[:c, c] = np.nan
使用此代码移动具有500列和一百万行(4 GB阵列)的浮点数组占用我的计算机大约12秒,但总时间将在很大程度上取决于索引和重新创建它的成本。