[英]Convert column of lists to 2D numpy array
我正在对 Pandas 数据框进行一些操作。 对于某个列,我需要将每个单元格转换为一个不难的 numpy 数组。 最终目标是从整个列中获得一个二维数组。 但是,当我执行以下操作时,我得到了一个一维数组,并且无法识别内部数组。
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 数组导出,以便我可以在我的机器学习模型中使用它们。
我认为直接从列表值创建一个数组会更好。
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'
)。
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
方法略有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
方法必须首先将每个子列表转换为数组。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.