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
方法则必须先将每个子列表都转换为数组。
np.array(df['new'].values.tolist())
ornp.stack(df['new'])
- user3483203tolist()
的意思是它不再是一个数组。 - roganjoshtolist
,那么您将会得到一个类型为对象,形状为(2,)
的数组。 - user3483203tolist()
将其转换为Python列表,然后您将其转换回数组?您可以只保留.values
吗?或者我有什么遗漏的吗? - roganjosh