Python - Pandas - 数据框:特定于行的条件列偏移量

Python - Pandas - Dataframe: Row Specific Conditional Column Offset

我正在尝试进行我无法解决的数据帧转换。我尝试了 Whosebug 和 pandas 文档中的多种方法:apply、apply(lambda: ...)、pivots 和 joins。此处列出的尝试太多,但不确定哪种方法最好,或者我是否尝试过使用错误语法的正确方法。

基本上,我有一个数据框,我需要 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() 函数似乎确实很容易做到这一点使用方式但有数千个公式,非常慢。我已经用 Python 超过 Excel 的好处出卖了我的工作场所,这是我第一次真正的尝试,所以速度对我来说非常重要,因为我试图说服我的同事 Python 可以比当前 excel 文件大小为 96Mb 的文件更快地吞噬此电子表格。

我非常接近 melt() 函数,然后获取以前的列号并向它们添加偏移量。但是,我在尝试使用 pivot 改革数据框时遇到了很多问题。 apply 或 apply(lambda) 不走运!

感谢任何人的帮助!

这不是特别优雅或简洁,但应该可以解决问题。我发现在 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. ]])

除此之外,为列添加 space 并将它们按正确的顺序排列只是一点点手工劳动。

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