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
我正在尝试进行我无法解决的数据帧转换。我尝试了 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