将pandas的数据框转换为NumPy数组。

698

我如何将pandas数据框转换为NumPy数组?

数据框:

import numpy as np
import pandas as pd

index = [1, 2, 3, 4, 5, 6, 7]
a = [np.nan, np.nan, np.nan, 0.1, 0.1, 0.1, 0.1]
b = [0.2, np.nan, 0.2, 0.2, 0.2, np.nan, np.nan]
c = [np.nan, 0.5, 0.5, np.nan, 0.5, 0.5, np.nan]
df = pd.DataFrame({'A': a, 'B': b, 'C': c}, index=index)
df = df.rename_axis('ID')

提供

label   A    B    C
ID                                 
1   NaN  0.2  NaN
2   NaN  NaN  0.5
3   NaN  0.2  0.5
4   0.1  0.2  NaN
5   0.1  0.2  0.5
6   0.1  NaN  0.5
7   0.1  NaN  NaN

我想将这个转换为NumPy数组,如下:

array([[ nan,  0.2,  nan],
       [ nan,  nan,  0.5],
       [ nan,  0.2,  0.5],
       [ 0.1,  0.2,  nan],
       [ 0.1,  0.2,  0.5],
       [ 0.1,  nan,  0.5],
       [ 0.1,  nan,  nan]])

另外,是否可以保留数据类型,像这样?

array([[ 1, nan,  0.2,  nan],
       [ 2, nan,  nan,  0.5],
       [ 3, nan,  0.2,  0.5],
       [ 4, 0.1,  0.2,  nan],
       [ 5, 0.1,  0.2,  0.5],
       [ 6, 0.1,  nan,  0.5],
       [ 7, 0.1,  nan,  nan]],
     dtype=[('ID', '<i4'), ('A', '<f8'), ('B', '<f8'), ('B', '<f8')])

15
为什么你需要这个?数据框架不是基于NumPy数组的吗?你应该可以在需要NumPy数组的地方使用数据框架。这就是为什么你可以在scikit-learn中使用数据框架,而函数要求提供NumPy数组。 - chrisfs
以下是关于dtypes和recarrays(也称为记录数组或结构化数组)的一些可能相关的链接:(1) https://dev59.com/O2kw5IYBdhLWcg3wXZX8 (2) https://stackoverflow.com/questions/52579601/convert-dataframe-with-strings-to-a-record-array - JohnE
2
注意:像这样将Pandas DataFrame转换为数组(或列表)可能表明存在其他问题。我强烈建议确保DataFrame是您特定用例的适当数据结构,并且Pandas不包括执行您感兴趣的操作的任何方法。 - AMC
16个回答

7

6

我在将数据框导出为ArcGIS表格时遇到了类似的问题,并从USGS找到了解决方案(https://my.usgs.gov/confluence/display/cdi/pandas.DataFrame+to+ArcGIS+Table)。 简而言之,您的问题有一个相似的解决方案:

df

      A    B    C
ID               
1   NaN  0.2  NaN
2   NaN  NaN  0.5
3   NaN  0.2  0.5
4   0.1  0.2  NaN
5   0.1  0.2  0.5
6   0.1  NaN  0.5
7   0.1  NaN  NaN

np_data = np.array(np.rec.fromrecords(df.values))
np_names = df.dtypes.index.tolist()
np_data.dtype.names = tuple([name.encode('UTF8') for name in np_names])

np_data

array([( nan,  0.2,  nan), ( nan,  nan,  0.5), ( nan,  0.2,  0.5),
       ( 0.1,  0.2,  nan), ( 0.1,  0.2,  0.5), ( 0.1,  nan,  0.5),
       ( 0.1,  nan,  nan)], 
      dtype=(numpy.record, [('A', '<f8'), ('B', '<f8'), ('C', '<f8')]))

5

试试这个:

np.array(df) 

array([['ID', nan, nan, nan],
   ['1', nan, 0.2, nan],
   ['2', nan, nan, 0.5],
   ['3', nan, 0.2, 0.5],
   ['4', 0.1, 0.2, nan],
   ['5', 0.1, 0.2, 0.5],
   ['6', 0.1, nan, 0.5],
   ['7', 0.1, nan, nan]], dtype=object)

更多信息请参考:[https://docs.scipy.org/doc/numpy/reference/generated/numpy.array.html] 适用于numpy 1.16.5和pandas 0.25.2。


5

阿萨姆提供的解决方案和你的有什么区别? - qaiser
刚刚尝试通过一个代码示例使其更完整和可用,这是我个人的偏好。 - user1460675
这个答案和这里第二个最受欢迎的答案有什么区别? - cs95

4
进一步回答meteore的问题,我找到了代码。
df.index = df.index.astype('i8')

对我来说不起作用。所以我在这里放置我的代码,方便其他人解决这个问题。

city_cluster_df = pd.read_csv(text_filepath, encoding='utf-8')
# the field 'city_en' is a string, when converted to Numpy array, it will be an object
city_cluster_arr = city_cluster_df[['city_en','lat','lon','cluster','cluster_filtered']].to_records()
descr=city_cluster_arr.dtype.descr
# change the field 'city_en' to string type (the index for 'city_en' here is 1 because before the field is the row index of dataframe)
descr[1]=(descr[1][0], "S20")
newArr=city_cluster_arr.astype(np.dtype(descr))

0
cs95's answer中所提到的,to_numpy()会将pandas dataframe一致地转换为numpy数组。另一方面,因为.values(如1, 2, 3, 4, 5中建议的)返回的是dataframe的底层数据,如果这不是一个numpy数组,它就不会返回一个numpy数组。

例如,如果某列是extension dtype,比如可空整数dtype(Int64),那么.values将返回一个pandas IntegerArray对象,而不是numpy ndarray,这可能不是期望的结果。然而,to_numpy()只能返回一个numpy数组。

df = pd.DataFrame({'A': [10, 20, 30]}, dtype='Int64')

type(df['A'].values)     # <class 'pandas.core.arrays.integer.IntegerArray'>

type(df['A'].to_numpy()) # <class 'numpy.ndarray'>

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,