Python - Pandas - 数据帧:行特定条件列偏移

时间:2015-07-08 15:08:54

标签: python pandas dataframe offset

我正在尝试进行无法解决的数据帧转换。我尝试过stackoverflow和pandas文档的多种方法:apply,apply(lambda:...),pivot和join。在这里列出太多的尝试,但不确定哪种方法是最好的,或者我可能用错误的语法尝试了正确的方法。

基本上,我有一个数据帧,我需要1)偏移列,2)偏移量的列数变化并取决于数据帧中的变量,3)在数据帧的末尾创建列需要适应偏移量,并且4)在新创建的间隔中放置零。

df1 = pd.DataFrame({'first' : ['John', 'Mary', 'Larry', 'jerry'], '1' : [5.5, 6.0,10,20], '2' : [100, 200, 300, 400], '3' : [150, 100, 240, 110], 'offset' : ([1,0,2,1])})
goal_df = pd.DataFrame({'first' : ['John', 'Mary', 'Larry', 'jerry'], '1' : [0.0, 6.0, 0.0, 0], '2' : [5.5, 200, 0.0, 20], '3' : [100, 100, 10, 400], '4' : [150, 0.0, 300, 110], '5' : [0.0, 0.0, 240, 0.0]})

df1
1         2        3    first      offset
5.5      100      150    John       1
6.0      200      100    Mary       0
10.0     300      240    Larry      2
20.0     400      110    jerry      1


goal_df
1      2    3    4    5  first
0    5.5  100  150    0   John
6  200.0  100    0    0   Mary
0    0.0   10  300  240  Larry
0   20.0  400  110    0  jerry

此数据集将包含c。 500行和c。 120列。偏移量将在0-12之间。我想过用基本的Python函数来做这件事,但我也发现很难,程序的时间消费者会破坏最终目的,即删除在Microsoft Excel中完成的一些任务。

我抱怨Excel对于像这样的大型任务是如何劣等,但似乎到目前为止excel中的当前电子表格offset()函数以一种非常容易使用的方式执行此操作,但有数千个公式,非常慢。我已经把我的工作场所卖给了Excel而不是Excel,这是我的第一次真正的试用,所以速度对我来说非常重要,因为我试图说服我的同事Python可以比这更快地吞噬这个电子表格当前excel文件,文件大小为96Mb。

我与melt()函数非常接近,然后获取前列数并将偏移量添加到它们。但是,我尝试使用数据透视表改造数据框时遇到了很多问题。申请或申请(lambda)没有运气!

感谢任何人的帮助!

1 个答案:

答案 0 :(得分:3)

这不是特别优雅或简洁,但应该做的伎俩。我发现在numpy中乱码的时候会更容易一些(也应该快一点)所以我首先从数据帧转换为数组。

arr    = df1.values[:,:-2]    # just the numbers
offset = df1.values[:,-1]     # just the offsets
column_pad = 2
arr2 = np.zeros( (arr.shape[0],arr.shape[1]+column_pad) )

这是关键代码,它只是将每一行移动偏移量。

for i, j in enumerate(offset):
    arr2[i,j:3+j] = arr[i]

array([[   0. ,    5.5,  100. ,  150. ,    0. ],
       [   6. ,  200. ,  100. ,    0. ,    0. ],
       [   0. ,    0. ,   10. ,  300. ,  240. ],
       [   0. ,   20. ,  400. ,  110. ,    0. ]])

除此之外,为列添加空间并按正确的顺序添加空间只是一点点的手工劳动。

df2 = df1.copy()
last_column = 6
for i in map(str,range(3,last_column)):
    df2[i] = 0
df2 = df2[ map(str,range(1,last_column))+['first','offset']]

然后将arr2加载到df2。

df2.loc[:,'1':'5'] = arr2

   1      2    3    4    5  first  offset
0  0    5.5  100  150    0   John       1
1  6  200.0  100    0    0   Mary       0
2  0    0.0   10  300  240  Larry       2
3  0   20.0  400  110    0  jerry       1