【问题标题】:Assigning multi-dimensional Numpy Array to a Pandas Series将多维 Numpy 数组分配给 Pandas 系列
【发布时间】:2022-01-24 13:28:35
【问题描述】:

背景

我有一个 numpy.ndarrayshape==(95,15)。我已经有了想要的Series.Index 名称,len(my_index)==95。我想创建一个Series,其中每个索引都与我的 95x15 numpy.ndarray 的行之一相关联。

变量名

  • pfit: 95x15 numpy.ndarray
  • my_index: 95x1 list(str)

采取的步骤

  1. 以下失败并出现相应错误:
my_series = pd.Series(index=my_index, dtype="object", data=pfit)
Traceback (most recent call last):

  File "C:\Users\gford1\AppData\Local\Temp\1/ipykernel_22244/2329315457.py", line 1, in <module>
    my_series = pd.Series(index=my_index, dtype="object", data=pfit)

  File "C:\Users\gford1\AppData\Local\Programs\Spyder\pkgs\pandas\core\series.py", line 439, in __init__
    data = sanitize_array(data, index, dtype, copy)

  File "C:\Users\gford1\AppData\Local\Programs\Spyder\pkgs\pandas\core\construction.py", line 577, in sanitize_array
    subarr = _sanitize_ndim(subarr, data, dtype, index, allow_2d=allow_2d)

  File "C:\Users\gford1\AppData\Local\Programs\Spyder\pkgs\pandas\core\construction.py", line 628, in _sanitize_ndim
    raise ValueError("Data must be 1-dimensional")

ValueError: Data must be 1-dimensional
  1. 因此,我必须遍历 my_index 并逐一添加 pfit 数组:
my_series = pd.Series(index=my_index, dtype="object")
i = 0
for idx in my_series.index:
    my_series[idx] = pfit[i]
    i+=1

#2 有效,但我相信有一种更好/更快的方法我不知道。

【问题讨论】:

  • data=list(pfit)) 有帮助吗?
  • 我想保留numpy数组
  • 我认为你不明白 Series 是什么,或者你的迭代做了什么。看my_series.values。这是否“保留”了数组?
  • 不要争论,但我确实了解系列是什么。我不想将 C 风格的 Numpy 数组不必要地转换为 Python 链表(即list(pfit)),然后仅在需要时将其作为 Numpy 数组再次检索。
  • 在系列中保留二维数组的唯一方法是将其整体放入一个单元格中。您不能一次将一行放入系列中,但仍将其作为二维数组检索。

标签: python pandas numpy


【解决方案1】:
In [283]: pfit=np.arange(12).reshape(3,4)
In [284]: pfit
Out[284]: 
array([[ 0,  1,  2,  3],
       [ 4,  5,  6,  7],
       [ 8,  9, 10, 11]])
In [285]: my_index=[1,2,3]

你的构造:

In [286]: my_series = pd.Series(index=my_index, dtype="object")
     ...: i = 0
     ...: for idx in my_series.index:
     ...:     my_series[idx] = pfit[i]
     ...:     i+=1
     ...: 
In [287]: my_series
Out[287]: 
1      [0, 1, 2, 3]
2      [4, 5, 6, 7]
3    [8, 9, 10, 11]
dtype: object
In [288]: my_series.values
Out[288]: 
array([array([0, 1, 2, 3]), array([4, 5, 6, 7]), array([ 8,  9, 10, 11])],
      dtype=object)

我的建议产生了同样的结果:

In [289]: list(pfit)
Out[289]: [array([0, 1, 2, 3]), array([4, 5, 6, 7]), array([ 8,  9, 10, 11])]
In [290]: S = pd.Series(index=my_index, data=list(pfit))
In [291]: S
Out[291]: 
1      [0, 1, 2, 3]
2      [4, 5, 6, 7]
3    [8, 9, 10, 11]
dtype: object
In [292]: S.values
Out[292]: 
array([array([0, 1, 2, 3]), array([4, 5, 6, 7]), array([ 8,  9, 10, 11])],
      dtype=object)

重新创建二维数组:

In [293]: np.stack(S.values)
Out[293]: 
array([[ 0,  1,  2,  3],
       [ 4,  5,  6,  7],
       [ 8,  9, 10, 11]])

数据框:

In [294]: df = pd.DataFrame(index=my_index, data=pfit)
In [295]: df
Out[295]: 
   0  1   2   3
1  0  1   2   3
2  4  5   6   7
3  8  9  10  11
In [296]: df.values
Out[296]: 
array([[ 0,  1,  2,  3],
       [ 4,  5,  6,  7],
       [ 8,  9, 10, 11]])

===

如果我更改pfit 的元素,更改将出现在Sdf 中。

In [305]: pfit[1,1] = 100
In [306]: pfit
Out[306]: 
array([[  0,   1,   2,   3],
       [  4, 100,   6,   7],
       [  8,   9,  10,  11]])
In [307]: S
Out[307]: 
1      [0, 1, 2, 3]
2    [4, 100, 6, 7]
3    [8, 9, 10, 11]
dtype: object
In [308]: df
Out[308]: 
   0    1   2   3
1  0    1   2   3
2  4  100   6   7
3  8    9  10  11

df 的情况下,data 数组直接用作_values 属性(或任何内部调用的属性),无需复制或更改。

在系列情况下,Out[289]pfit 的 1d views 的列表。因此,两者都出现了对第二个视图的更改。

但是从系列中重新创建一个二维数组,就像 [293] 所做的那样,会生成一个副本,一个新的二维数组。

我们可以通过查看前面显示的数组 ipython 看到这种差异 - 尽管了解这里发生的事情还需要了解 numpy 视图和对象引用。

In [309]: Out[292]
Out[309]: 
array([array([0, 1, 2, 3]), array([  4, 100,   6,   7]),
       array([ 8,  9, 10, 11])], dtype=object)
In [310]: Out[293]
Out[310]: 
array([[ 0,  1,  2,  3],
       [ 4,  5,  6,  7],
       [ 8,  9, 10, 11]])

【讨论】:

    猜你喜欢
    • 2019-05-05
    • 1970-01-01
    • 2015-07-06
    • 1970-01-01
    • 2011-12-24
    • 2018-04-11
    • 2018-07-30
    • 2019-03-12
    相关资源
    最近更新 更多