【问题标题】:Reshaping a 3D array to a 2D array to produce a DataFrame: keep track of indices to produce column names将 3D 数组重塑为 2D 数组以生成 DataFrame:跟踪索引以生成列名
【发布时间】:2020-12-16 08:18:49
【问题描述】:

以下代码从第一个轴上的 3D 数组生成pandas.DataFrame。我手动创建列名称(定义cols):是否有更内置的方法来执行此操作(以避免潜在的错误,例如关于 C 顺序)?

--> 我正在寻找一种方法来保证在reshape 操作之后遵守索引的顺序(这里它依赖于range(nrow)range(ncol) 上的正确迭代顺序)。

import numpy as np
import pandas as pd

nt = 6 ; nrow = 4 ; ncol = 3 ; shp = (nt, nrow, ncol)

np.random.seed(0)
a = np.array(np.random.randint(0, 1000, nt*nrow*ncol)).reshape(shp)

# This is the line I think should be improved --> any numpy function or so?
cols = [str(i) + '-' + str(j) for i in range(nrow) for j in range(ncol)]

adf = pd.DataFrame(a.reshape(nt, -1), columns = cols)

print(adf)

   0-0  0-1  0-2  1-0  1-1  1-2  2-0  2-1  2-2  3-0  3-1  3-2
0  684  559  629  192  835  763  707  359    9  723  277  754
1  804  599   70  472  600  396  314  705  486  551   87  174
2  600  849  677  537  845   72  777  916  115  976  755  709
3  847  431  448  850   99  984  177  755  797  659  147  910
4  423  288  961  265  697  639  544  543  714  244  151  675
5  510  459  882  183   28  802  128  128  932   53  901  550

编辑

说明为什么我不喜欢我的解决方案 - 编写在技术上有效但产生错误结果的代码太容易了(反转 ijnrowncol):

wrongcols1 = [str(i) + '-' + str(j) for i in range(ncol) for j in range(nrow)]
adf2 = pd.DataFrame(a.reshape(nt, -1), columns=wrongcols1)
print(adf2)
   0-0  0-1  0-2  0-3  1-0  1-1  1-2  1-3  2-0  2-1  2-2  2-3
0  684  559  629  192  835  763  707  359    9  723  277  754
1  804  599   70  472  600  396  314  705  486  551   87  174
2  600  849  677  537  845   72  777  916  115  976  755  709
3  847  431  448  850   99  984  177  755  797  659  147  910
4  423  288  961  265  697  639  544  543  714  244  151  675
5  510  459  882  183   28  802  128  128  932   53  901  550

wrongcols2 = [str(j) + '-' + str(i) for i in range(nrow) for j in range(ncol)]
adf3 = pd.DataFrame(a.reshape(nt, -1), columns=wrongcols2)
print(adf3)
   0-0  1-0  2-0  0-1  1-1  2-1  0-2  1-2  2-2  0-3  1-3  2-3
0  684  559  629  192  835  763  707  359    9  723  277  754
1  804  599   70  472  600  396  314  705  486  551   87  174
2  600  849  677  537  845   72  777  916  115  976  755  709
3  847  431  448  850   99  984  177  755  797  659  147  910
4  423  288  961  265  697  639  544  543  714  244  151  675
5  510  459  882  183   28  802  128  128  932   53  901  550

【问题讨论】:

  • 您希望改进代码的哪一部分?列生成?
  • 是的@sammywemmy,我在代码中确定了这一行-->这里它依赖于我自己对range(nrow)range(ncol)的迭代,这是次优的并且容易出错...-->我如何生成列名应该减少“手动”

标签: python python-3.x pandas numpy-ndarray


【解决方案1】:

试试这个,看看它是否适合你的用例:

通过np.indicesnp.dstacknp.vstack 的组合生成列:

columns = np.vstack(np.dstack(np.indices((nrow, ncol))))

array([[0, 0],
       [0, 1],
       [0, 2],
       [1, 0],
       [1, 1],
       [1, 2],
       [2, 0],
       [2, 1],
       [2, 2],
       [3, 0],
       [3, 1],
       [3, 2]])

现在通过mapjoinlist comprehension 的组合转换为字符串:

columns = ["-".join(map(str, entry)) for entry in columns]
['0-0',
 '0-1',
 '0-2',
 '1-0',
 '1-1',
 '1-2',
 '2-0',
 '2-1',
 '2-2',
 '3-0',
 '3-1',
 '3-2']

让我们知道它是怎么回事。

【讨论】:

  • 工作正常,谢谢!我很惊讶没有更直接的 numpy 函数来实现这一点,虽然......(在接受之前等待一下,看看是否有任何其他建议弹出)
  • @ztl,再等一会儿是个好主意;对我来说也是很好的学习过程。我认为 numpy 函数的强大之处在于它的可组合性。
【解决方案2】:

您可以尝试使用pd.MultiIndex 来构建您的层次结构。

首先将您的cols 重新定义为listtuples

cols = [(i, j) for i in range(nrow) for j in range(ncol)]

然后用cols构造多索引:

multi_cols = pd.MultiIndex.from_tuples(cols)

并构建数据框:

adf = pd.DataFrame(a.reshape(nt, -1), columns=multi_cols)

结果:

              0           1           2           3
      0   1   2   0   1   2   0   1   2   0   1   2
0   684 559 629 192 835 763 707 359   9 723 277 754
1   804 599  70 472 600 396 314 705 486 551  87 174
2   600 849 677 537 845  72 777 916 115 976 755 709
3   847 431 448 850  99 984 177 755 797 659 147 910
4   423 288 961 265 697 639 544 543 714 244 151 675
5   510 459 882 183  28 802 128 128 932  53 901 550

元素的访问:

print(adf[1][2][0])
>>> 763

【讨论】:

  • 感谢@rftr,但它仍然依赖于cols 的手动定义,它本身依赖于range(nrow)range(ncol) 上的迭代完成的适当顺序。我正在寻找一种解决方案,以保证遵守reshape 操作后修改索引的顺序...
  • @ztl:我看到了@sammywemmy 的答案,但我也想学习:你能不能再解释一下range 函数的问题是什么?我想我没明白。
  • 我编辑了我的问题以使其更加明确,并以错误的结果进行说明(尽管使用这种定义 cols... 的方式很容易发生这种情况)
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2017-09-18
  • 1970-01-01
  • 1970-01-01
  • 2016-01-17
  • 1970-01-01
  • 1970-01-01
  • 2019-09-12
相关资源
最近更新 更多