将列表的列转换为2D numpy数组

时间:2019-01-16 20:59:38

标签: python arrays pandas list numpy

我正在对Pandas数据框进行一些操作。对于特定的列,我需要将每个单元格转换为不难的numpy数组。最终目标是从整个列中获得2D数组。但是,当我执行以下操作时,我得到了一维数组,并且内部数组无法识别。

df = pd.DataFrame({'col': ['abc', 'def']})
mapping = {v: k for k, v in enumerate('abcdef')}
df['new'] = df['col'].apply(lambda x: list(x))
df['new'].apply(lambda x: np.array([mapping[i] for i in x])).values

这给出了:

array([array([0, 1, 2]), array([3, 4, 5])], dtype=object)

,形状为(2,),表示无法识别内部数组。

如果我做s.reshape(2,-1),则形状得到(2,1)而不是(2,3)

感谢任何帮助!


说明:

以上仅是一个玩具示例。我正在做的是使用IMDB数据集对机器学习进行预处理。我必须将评论列中的每个值转换为一个词嵌入,即一个numpy数组。现在的挑战是将所有这些数组作为2D数组输出,以便可以在我的机器学习模型中使用它们。

2 个答案:

答案 0 :(得分:1)

我认为最好直接从列表值创建一个数组。

 df
   col        new
0  abc  [a, b, c]
1  def  [d, e, f]

arr = np.array(df['new'].tolist())
arr
# array([['a', 'b', 'c'],
#        ['d', 'e', 'f']], dtype='<U1')

arr.shape
# (2, 3)

主要免责声明:仅当子列表中的元素数均相同时,此方法才有效。如果不是,那将意味着它们是不规则的数组,并且numpy将无法使用有效的内存格式来表示您的数组(因此,dtype='object')。

答案 1 :(得分:0)

In [2]: import pandas as pd
In [3]: df = pd.DataFrame({'col': ['abc', 'def']})
   ...: mapping = {v: k for k, v in enumerate('abcdef')}
   ...: df['new'] = df['col'].apply(lambda x: list(x))

In [7]: df['new']
Out[7]: 
0    [a, b, c]
1    [d, e, f]
Name: new, dtype: object
In [8]: df['new'].values
Out[8]: array([list(['a', 'b', 'c']), list(['d', 'e', 'f'])], dtype=object)

np.stack的行为很像np.array,将元素连接到新的初始轴上:

In [9]: np.stack(df['new'].values)
Out[9]: 
array([['a', 'b', 'c'],
       ['d', 'e', 'f']], dtype='<U1')

或您选择的另一个轴上

In [10]: np.stack(df['new'].values, axis=1)
Out[10]: 
array([['a', 'd'],
       ['b', 'e'],
       ['c', 'f']], dtype='<U1')

np.array也可以将对象数组转换为列表(如@coldspeed所示):

In [11]: df['new'].values.tolist()
Out[11]: [['a', 'b', 'c'], ['d', 'e', 'f']]
In [12]: np.array(df['new'].values.tolist())
Out[12]: 
array([['a', 'b', 'c'],
       ['d', 'e', 'f']], dtype='<U1')

关于速度,让我们做一个更大的数组:

In [16]: arr = np.frompyfunc(lambda x: np.arange(1000),1,1)(np.arange(1000))
In [17]: arr.shape
Out[17]: (1000,)
In [18]: np.stack(arr).shape
Out[18]: (1000, 1000)
In [20]: np.array(arr.tolist()).shape
Out[20]: (1000, 1000)

In [21]: timeit np.stack(arr).shape
5.24 ms ± 190 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)
In [22]: timeit np.array(arr.tolist()).shape
4.45 ms ± 138 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)

基本相同,np.array方法略有优势。

stack类似的

vstack根据需要扩展每个元素的尺寸。用concatenate跳过它会更快一些:

In [27]: timeit np.concatenate(arr).reshape(-1,1000).shape
4.04 ms ± 12.3 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)

arr包含数组。如果它包含列表,则array(arr.tolist())方法会更好(相对),因为它只有一个列表(列表)可以转换为数组。 stack方法必须首先将每个子列表转换为数组。