按对角线旋转数据框

2024-04-03

给定一个数据框

   col1  col2  col3
0     1     4     7
1     2     5     8
2     3     6     9

如何得到这样的东西:

         0    1    2
               
0      1.0  2.0  3.0
1      5.0  4.0  7.0
2      9.0  6.0  NaN
3      NaN  8.0  NaN

如果我们将数据帧视为索引数组i, j那么 diag n 中就是那些abs (i-j) = n

一个优点是能够选择顺序:

intercale = True ,first_diag = '左'

         0    1    2
               
0      1.0  2.0  3.0
1      5.0  4.0  7.0
2      9.0  6.0  NaN
3      NaN  8.0  NaN

插值 = False,first_diag ='左'

         0    1    2
               
0      1.0  2.0  3.0
1      5.0  6.0  7.0
2      9.0  4.0  NaN
3      NaN  8.0  NaN

插值 = True,first_diag ='右'

         0    1    2
               
0      1.0  4.0  7.0
1      5.0  2.0  3.0
2      9.0  8.0  NaN
3      NaN  6.0  NaN

intercalate = False,first_diag ='正确'

         0    1    2
               
0      1.0  4.0  7.0
1      5.0  8.0  3.0
2      9.0  2.0  NaN
3      NaN  6.0  NaN

甚至可以通过选择从下角到上角或相反的方向来进行排序的另一个自由度。或者选择另一个主对角线

我对熊猫的态度

df2 = df.reset_index().melt('index').assign(variable = lambda x: x.variable.factorize()[0])
df2['diag'] = df2['index'].sub(df2['variable']).abs()
new_df = (df2.assign(index = df2.groupby('diag').cumcount())
             .pivot_table(index = 'index',columns = 'diag',values = 'value'))
print(new_df)
diag     0    1    2
index               
0      1.0  2.0  3.0
1      5.0  4.0  7.0
2      9.0  6.0  NaN
3      NaN  8.0  NaN

我想知道是否有更简单的方法可以做到这一点,也许使用 numpy


情况#1:每列输出中的元素顺序并不重要

方法#1:这是 NumPy 的一种方法 -

def diagonalize(a): # input is array and output is df
    n = len(a)    
    r = np.arange(n)

    idx = np.abs(r[:,None]-r)
    lens = np.r_[n,np.arange(2*n-2,0,-2)]
    split_idx = lens.cumsum()

    b = a.flat[idx.ravel().argsort()]
    v = np.split(b,split_idx[:-1])
    return pd.DataFrame(v).T

样本运行 -

In [110]: df
Out[110]: 
   col1  col2  col3  col4
0     1     2     3     4
1     5     6     7     8
2     9    10    11    12
3    13    14    15    16

In [111]: diagonalize(df.to_numpy(copy=False))
Out[111]: 
      0     1     2     3
0   1.0   2.0   3.0   4.0
1   6.0   5.0   8.0  13.0
2  11.0   7.0   9.0   NaN
3  16.0  10.0  14.0   NaN
4   NaN  12.0   NaN   NaN
5   NaN  15.0   NaN   NaN

方法#2:与之前类似,但完全基于 NumPy 并且无循环 -

def diagonalize_v2(a): # input, outputs are arrays
    # Setup params
    n = len(a)    
    r = np.arange(n)

    # Get indices based on "diagonalization" (distance off diagonal)
    idx = np.abs(r[:,None]-r)
    lens = np.r_[n,np.arange(2*n-2,0,-2)]

    # Values in the order of "diagonalization"
    b = a.flat[idx.ravel().argsort()]

    # Get a mask for the final o/p where elements are to be assigned
    mask = np.arange(lens.max())[:,None]<lens

    # Setup o/p and assign
    out = np.full(mask.shape,np.nan)
    out.T[mask.T] = b
    return out

样本运行 -

In [2]: a
Out[2]: 
array([[ 1,  2,  3,  4],
       [ 5,  6,  7,  8],
       [ 9, 10, 11, 12],
       [13, 14, 15, 16]])

In [3]: diagonalize_v2(a)
Out[3]: 
array([[ 1.,  2.,  3.,  4.],
       [ 6.,  5.,  8., 13.],
       [11.,  7.,  9., nan],
       [16., 10., 14., nan],
       [nan, 12., nan, nan],
       [nan, 15., nan, nan]])

情况#2:每列中元素的顺序很重要

我们有两个额外的输入参数来管理订单。该解决方案将是一个修改版本,其灵感主要来自Approach #1 -

def diagonalize_generic(a, intercale = True ,first_diag = 'left'):
    # Setup params
    n = len(a)    
    r = np.arange(n)

    # Get indices based on "diagonalization" (distance off diagonal)
    idx = np.abs(r[:,None]-r)
    lens = np.r_[n,np.arange(2*n-2,0,-2)]

    if first_diag=='left':
        w = np.triu(np.ones(n, dtype=int))
    elif first_diag=='right':
        w = np.tril(np.ones(n, dtype=int))
    else:
        raise Exception('Wrong first_diag value!')

    order = np.lexsort(np.c_[w.ravel(),idx.ravel()].T)

    split_idx = lens.cumsum()
    o_split = np.split(order,split_idx[:-1])

    f = a.flat

    if intercale==1:
        v = [f[o_split[0]]] + [f[o.reshape(2,-1).ravel('F')] for o in o_split[1:]]
    else:
        v = [f[o] for o in o_split]
    return pd.DataFrame(v).T

样品运行

输入为数组:

In [53]: a
Out[53]: 
array([[1, 4, 7],
       [2, 5, 8],
       [3, 6, 9]])

不同场景:

In [54]: diagonalize_generic(a, intercale = True, first_diag = 'left')
Out[54]: 
     0    1    2
0  1.0  2.0  3.0
1  5.0  4.0  7.0
2  9.0  6.0  NaN
3  NaN  8.0  NaN

In [55]: diagonalize_generic(a, intercale = False, first_diag = 'left')
Out[55]: 
     0    1    2
0  1.0  2.0  3.0
1  5.0  6.0  7.0
2  9.0  4.0  NaN
3  NaN  8.0  NaN

In [56]: diagonalize_generic(a, intercale = True, first_diag = 'right')
Out[56]: 
     0    1    2
0  1.0  4.0  7.0
1  5.0  2.0  3.0
2  9.0  8.0  NaN
3  NaN  6.0  NaN

In [57]: diagonalize_generic(a, intercale = False, first_diag = 'right')
Out[57]: 
     0    1    2
0  1.0  4.0  7.0
1  5.0  8.0  3.0
2  9.0  2.0  NaN
3  NaN  6.0  NaN
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

按对角线旋转数据框 的相关文章

随机推荐

  • 如何通过azure云服务上的kubernetes检查持久卷的内容

    我已将软件打包到容器中 我需要通过Azure容器服务将容器放入集群 该软件具有目录的输出 src data 我想访问整个目录的内容 搜索后 我必须解决 在azure上使用Blob存储 但是搜索后 我找不到可执行方法 使用持久卷 但是我找到的
  • Python Pygame 游戏灯光

    我正在制作一款 2D 横向卷轴游戏 游戏中的一个物品是火炬 我有一个手臂可以旋转的玩家 我们可以获取手臂的角度 我正在寻找跟随手臂角度的三角形光束形状 我有一些想法 比如在整个屏幕上放置一个 alpha 图像 并根据手臂角度单独从每个像素中
  • 具有扩展方法的 Kotlin 数据绑定

    我正在尝试在 Android 的数据绑定中使用 Kotlin 扩展方法 例如 调用 onclick 处理程序 所以我编写了这段代码 posttest list item xml
  • 输入文件大小和内容在 macOS 上不会更新

    我编写了一个基于网络的小型工具 它使用文件输入来读取不断变化的文件 用户手动选择它 一次 JavaScript 会跟踪它的更改时间 上次文件修改时间和文件大小 如果已更改 则会再次读取文件内容 这在 Windows 上的所有浏览器中都可以正
  • PHP AWS SDK 3错误:AWS HTTP错误:cURL错误6:无法解析主机:s3.oregon.amazonaws.com

    我正在尝试连接到 AWS 版本 3 SDK 存储桶 但是 我收到以下错误 PHP 致命错误 未捕获异常 Aws S3 Exception S3Exception 并显示消息 在 上执行 PutObject 时出错 https s3 oreg
  • 我如何在 codeigniter 中创建一个虚荣网址

    我如何在 codeigniter 中创建一个虚荣网址 我在框架中执行此操作确实遇到困难 而且似乎没有任何好的答案 有可能 我正在我的一个项目中使用它 这是 CodeIgniter 论坛上的一个帖子 展示了如何做到这一点 http codei
  • 您遇到过的最好的源代码注释是什么? [关闭]

    就目前情况而言 这个问题不太适合我们的问答形式 我们希望答案得到事实 参考资料或专业知识的支持 但这个问题可能会引发辩论 争论 民意调查或扩展讨论 如果您觉得这个问题可以改进并可能重新开放 访问帮助中心 help reopen questi
  • 使用 .NET Core 时是否需要 AssemblyInfo?

    之前 AssemblyInfo cs文件是由 Visual Studio 自动创建的 用于包含程序集范围的属性 如 AssemblyVersion AssemblyName 等 在 NET Core 和 ASP NET Core 中 pro
  • T-SQL - 按周进行透视

    我目前正在尝试创建一个 T SQL 它运行表中的交货列表 并按客户和仓库对它们进行分组 因此每一行都将是 客户 仓库 总价值 称为费率的列的总和 然而 客户希望将 总价值 分为过去 9 周 因此 我们将拥有如下列 而不是总价值 22 01
  • 为什么我的 rustup rust-toolchain 文件没有覆盖默认值?

    我想使用 Rust 每晚 构建来与 Arrow 和 Datafusion 配合使用 根据这个帖子 https stackoverflow com questions 58226545 how to switch between rust t
  • ESP8266 I2C从机不确认数据

    我有一个 TM4C123 处理器作为 I2C 主处理器 一个 ESP8266 作为从处理器 对于 ESP 我使用的是 Arduino IDE 并在 2 5 2 版安装了 ESP8266 支持 它应该支持 I2C 从模式 但是 我无法让它工作
  • NsdManager.DiscoveryListener.onServiceFound 的 NsdServiceInfo 中 Host 为 null

    我试图将 NsdServiceInfo 的 mHost 作为参数传递给 NsdManager DiscoveryListener onServiceFound 但它为空 我有两个 Android 设备 其中设备 1 是服务器 设备 2 是客
  • 如何添加到表过滤器以允许多个复选框选择以及从下拉列表中进行过滤?

    我有一个可以通过多个复选框以及 选择 下拉列表进行过滤的表格 本质上 我想要做的是单击多个复选框 以便找到包含该类 例如类 1 和 3 的每一行 然后按位置对其进行过滤 此时我已经非常接近了 我可以从复选框中选择位置 这也是一个类 两个字母
  • 基于正则表达式以闪亮方式突出显示 DT 中的单词

    使用闪亮的 DT 我希望能够突出显示所选单词 环境searchHighlight TRUE接近我想要的 但这也会突出显示包含搜索的单词 例如 如果我搜索 on 它也会匹配 stone 突出显示中间的 on 示例图片 我可以优化搜索选项reg
  • 在单遍中执行多次还原

    在流的单次传递中执行多次归约的习惯用法是什么 是否只是拥有一个大的减速器类 即使这违反了 SRP 如果需要不止一种类型的减速计算 大概您希望避免进行多次传递 因为管道阶段可能很昂贵 或者您希望避免收集中间值以便通过多个收集器运行它们 因为存
  • 如何对迭代器进行排序而不将其全部放入向量中?

    我正在构建一个类似于生成器的通用接口 它将数据从一个流传输到另一个流 最终执行以下操作 file gt toCsv gt filter gt sort gt filter 我知道如何对向量 切片进行排序 但是如何从传入流 迭代器中进行排序而
  • 文件系统观察器内部缓冲区溢出

    当我尝试监视网络路径上的文件夹 DFS 分布式文件系统 时 出现 System IO Internal BufferOverflowException 异常 同时进行许多更改 当 FileSystemWatcher 监视不使用此文件系统的本
  • Google G Suite SAML SSO 域登录页面

    我正在使用 Google G Suite 并创建了一个使用 G Suite SAML 管理用户登录的应用程序 看 一切都很顺利 但是当用户没有登录我们的 G Suite 帐户并且也登录了他们自己的 Google 帐户时 我遇到了问题 在这种
  • 在弹性中映射 geo_point 字段数组

    我想将一些 JSON 持久保存到 elastic search 中 看起来有点像这样 name value points lat 0 0 lon 0 0 lat 1 0 lon 1 0 点是弹性中 geo point 类型的列表 因为它们是
  • 按对角线旋转数据框

    给定一个数据框 col1 col2 col3 0 1 4 7 1 2 5 8 2 3 6 9 如何得到这样的东西 0 1 2 0 1 0 2 0 3 0 1 5 0 4 0 7 0 2 9 0 6 0 NaN 3 NaN 8 0 NaN 如