【问题标题】:Put a 2d Array into a Pandas Series将二维数组放入 Pandas 系列
【发布时间】:2016-12-14 21:13:55
【问题描述】:

我有一个 2D Numpy 数组,我想将它放入 pandas Series(不是 DataFrame):

>>> import pandas as pd
>>> import numpy as np
>>> a = np.zeros((5, 2))
>>> a
array([[ 0.,  0.],
       [ 0.,  0.],
       [ 0.,  0.],
       [ 0.,  0.],
       [ 0.,  0.]])

但这会引发错误:

>>> s = pd.Series(a)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/miniconda/envs/pyspark/lib/python3.4/site-packages/pandas/core/series.py", line 227, in __init__
    raise_cast_failure=True)
  File "/miniconda/envs/pyspark/lib/python3.4/site-packages/pandas/core/series.py", line 2920, in _sanitize_array
    raise Exception('Data must be 1-dimensional')
Exception: Data must be 1-dimensional

可以通过 hack:

>>> s = pd.Series(map(lambda x:[x], a)).apply(lambda x:x[0])
>>> s
0    [0.0, 0.0]
1    [0.0, 0.0]
2    [0.0, 0.0]
3    [0.0, 0.0]
4    [0.0, 0.0]

有没有更好的办法?

【问题讨论】:

  • 默认情况下,Pandas 获取 np 数组的形状并相应地分配 DataFrame。所以你需要欺骗你的 np 数组的形状......这就是你“破解”所做的,尽管一次一行。
  • 关于如何使用矩阵运算将每一行包装在列表中的任何想法?
  • 只是出于好奇,你为什么要这个?
  • 您可能想尝试元组。 x:y 分隔符为“:”,但请注意,当 numpy 在矩阵中看到对象时,它将默认为“对象”计算模式与“C”计算模式。
  • @juanpa.arrivillaga 机器学习。我想将一个矢量化的文本语料库附加到包含标签和其他特征的 DataFrame 中。这种方式更容易过滤整个数据集,并且对于子集可能没有完整标签集的较小数据集特别方便。我想要一个系列中的所有列,因为我不想跟踪 DataFrame 中每个词汇表的列。如果你有更好的系统来管理这个,我很想听听!

标签: python pandas numpy


【解决方案1】:

好吧,你可以使用numpy.ndarray.tolist函数,像这样:

>>> a = np.zeros((5,2))
>>> a
array([[ 0.,  0.],
       [ 0.,  0.],
       [ 0.,  0.],
       [ 0.,  0.],
       [ 0.,  0.]])
>>> a.tolist()
[[0.0, 0.0], [0.0, 0.0], [0.0, 0.0], [0.0, 0.0], [0.0, 0.0]]
>>> pd.Series(a.tolist())
0    [0.0, 0.0]
1    [0.0, 0.0]
2    [0.0, 0.0]
3    [0.0, 0.0]
4    [0.0, 0.0]
dtype: object

编辑:

完成类似结果的更快方法是简单地执行pd.Series(list(a))。这将生成一系列 numpy 数组而不是 Python 列表,因此应该比返回 Python 列表列表的a.tolist 更快。

【讨论】:

  • 谢谢,大约 25 列以下的列速度更快,但如果有数百或数千列,则速度要慢得多。
  • 我发现了另一种更快的方法。请参阅编辑后的答案。
  • 很好,感谢您的坚持!它是所有场景中最快的。
【解决方案2】:
 pd.Series(list(a))

始终比

pd.Series(a.tolist())

测试了 20,000,000 -- 500,000 行

a = np.ones((500000,2))

仅显示 1,000,000 行:

%timeit pd.Series(list(a))
1 loop, best of 3: 301 ms per loop

%timeit pd.Series(a.tolist())
1 loop, best of 3: 261 ms per loop

【讨论】:

  • 只有两列时确实如此。试试几千,看看会发生什么。
猜你喜欢
  • 2019-05-05
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-09-25
  • 2022-01-24
  • 2021-01-12
相关资源
最近更新 更多