如何将Pandas系列或索引转换为NumPy数组?

302

如何将DataFrame的索引或列作为NumPy数组或Python列表获取?


此外,相关内容:将pandas数据框转换成NumPy数组 - cs95
2
这个回答解决了你的问题吗?将 Pandas Dataframe 转换为NumPy数组 - AMC
1
注意:像这样将Pandas DataFrame转换为数组(或列表)可能表明存在其他问题。我强烈建议确保DataFrame是您特定用例的适当数据结构,并且Pandas不包括执行您感兴趣的操作的任何方法。 - AMC
关于我投票重新开放这个问题:从技术上讲,pandas系列与pandas数据框不同。答案可能相同,但问题肯定是不同的。 - Serge Stroobandt
8个回答

379

要获得一个 NumPy 数组,您应该使用 values 属性:

In [1]: df = pd.DataFrame({'A': [1, 2, 3], 'B': [4, 5, 6]}, index=['a', 'b', 'c']); df
   A  B
a  1  4
b  2  5
c  3  6

In [2]: df.index.values
Out[2]: array(['a', 'b', 'c'], dtype=object)

这是通过访问已存储的数据进行的,因此不需要进行转换。

注意:许多其他Pandas对象也提供了此属性。

In [3]: df['A'].values
Out[3]: Out[16]: array([1, 2, 3])
获取索引列表,调用 tolist 函数:
In [4]: df.index.tolist()
Out[4]: ['a', 'b', 'c']

同样地,对于列也是如此。


1
注意:.values已被弃用,如果您想要一个NumPy数组,则建议使用.to_numpy()进行替换。您能详细说明“这会访问数据的存储方式,因此不需要转换”吗? - AMC
cs95的回答(https://dev59.com/XWQm5IYBdhLWcg3w6SdR#54324513)对`.values`、`.to_numpy()`和`.array`进行了很好的解释。 - AMC

75
您可以使用df.index访问索引对象,然后使用df.index.tolist()以列表形式获取其值。同样地,您可以针对Series使用df['col'].tolist()

它返回的是instanceMethod而不是列表数组。 - V Shreyas
12
@VShreyas,df.index.values.tolist()怎么样? - LancelotHolmes
3
df.index.tolist() 返回的不是一个实例方法,而是索引列表。它是 pandas 索引上定义的一个方法。虽然先调用值也是一种可能性,但将工作委托给 numpy 不是一种更正,只是另一种选择。 - ayhan

70

pandas >= 0.24

使用以下方法替代.values,旧用法已被弃用!

从v0.24.0版本开始,我们将有两种全新的、更加推荐的方法,用于从IndexSeriesDataFrame对象中获取NumPy数组:它们分别是to_numpy().array。关于使用方式,文档提到:

我们没有删除或废弃Series.valuesDataFrame.values,但我们强烈建议使用.array.to_numpy()来替代。

有关更多信息,请参见v0.24.0发行说明的此部分


to_numpy()方法

df.index.to_numpy()
# array(['a', 'b'], dtype=object)

df['A'].to_numpy()
#  array([1, 4])

默认情况下,将返回视图。对其进行的任何修改都将影响原始数据。

v = df.index.to_numpy()
v[0] = -1
 
df
    A  B
-1  1  2
b   4  5

如果您需要复制而不是原地操作,请使用to_numpy(copy=True)
v = df.index.to_numpy(copy=True)
v[-1] = -123
 
df
   A  B
a  1  2
b  4  5

注意,此函数也适用于DataFrames(而.array则不适用)。

array属性
该属性返回支持索引/系列的ExtensionArray对象。

pd.__version__
# '0.24.0rc1'

# Setup.
df = pd.DataFrame([[1, 2], [4, 5]], columns=['A', 'B'], index=['a', 'b'])
df

   A  B
a  1  2
b  4  5

<!- ->

df.index.array    
# <PandasArray>
# ['a', 'b']
# Length: 2, dtype: object

df['A'].array
# <PandasArray>
# [1, 4]
# Length: 2, dtype: int64

从这里开始,可以使用list获取列表:

list(df.index.array)
# ['a', 'b']

list(df['A'].array)
# [1, 4]

或者,直接调用.tolist()
df.index.tolist()
# ['a', 'b']

df['A'].tolist()
# [1, 4]

关于返回的内容,文档中提到:
对于由普通NumPy数组支持的SeriesIndexSeries.array将返回一个新的arrays.PandasArray,它是一个薄的(无需复制)numpy.ndarray包装器。 arrays.PandasArray本身并不特别有用,但它确实提供了与pandas或第三方库定义的任何扩展数组相同的接口。
因此,总结一下,.array将返回以下内容之一:
1.支持Index / Series的现有ExtensionArray,或者 2.如果有支持系列的NumPy数组,则创建一个新的ExtensionArray对象,作为对底层数组的薄包装。
添加两个新方法的原因
这些函数是在两个GitHub问题GH19954GH23623的讨论下添加的。
具体而言,文档提到了理由:

[...]使用.values时不清楚返回值是实际数组、其某些转换还是pandas定制数组之一(如Categorical)。例如,对于PeriodIndex.values每次都会生成一个新的周期对象ndarray。[...]

这两个函数旨在提高API的一致性,这是朝着正确方向迈出的重要一步。
最后,.values在当前版本中不会被弃用,但我预计在将来的某个时候可能会发生这种情况,因此我建议用户尽快迁移到较新的API。

S = pd.Series([3, 4]); np.asarray(S)是S.values让我感到惊讶;您知道这是否有记录在任何地方吗?(numpy 1.21.5,pandas 1.3.5) - denis

49

如果你正在处理一个多级索引的数据框,你可能只对提取其中一个名称的列感兴趣。您可以使用以下方式实现:

df.index.get_level_values('name_sub_index')

当然,name_sub_index必须是df.index.names中的一个元素,这个df.index.namesFrozenList类型的。


16

自从pandas v0.13版以后,你也可以使用get_values方法:

df.index.get_values()

5
这个和.values有区别吗?(我更新了版本信息,因为这个函数从0.13.0文档中出现。) - Andy Hayden
@Andy Hayden:难道一个区别不是.get_values是获取当前值的官方方式,而.values(例如在多索引上)可能会返回已删除行或列的索引值吗? - Ezekiel Kruglick
@EzekielKruglick 所以它总是一份副本?链接到的文档非常简单,我认为你不会得到这样的重复项(即使它们在MI中,也不会在.values中)。很高兴看到一个演示这一点的例子! - Andy Hayden
@AndyHayden:我想我误解了你的评论。你是对的,.values 是好的,.level 给出过时的信息,而 get_values 则可以正确地获取当前值,排除了被删除的行/列。原始的 GitHub 问题链接:github.com/pydata/pandas/issues/3686 但是我刚刚检查了一下,看起来 .values(当然!)提供了最新的信息,只是以我认为我们讨��的形式不同。 - Ezekiel Kruglick
1
@AndyHayden,没有区别。get_values只是调用.values。这需要更多的字符输入。 - cs95

2

一种更近期的方法是使用 .to_numpy() 函数。

如果我有一个包含列 'price' 的数据框,我可以按如下方式进行转换:

priceArray = df['price'].to_numpy()

您可以将数据类型(例如float或object)作为函数的参数传递。

0

我将pandas的dataframe转换为list,然后使用基本的list.index()。就像这样:

dd = list(zone[0]) #Where zone[0] is some specific column of the table
idx = dd.index(filename[i])

你的索引值为idx


然后使用基本的list.index()。这与将Series转换为列表的问题有何关系? - AMC

-1
以下是将数据框列转换为NumPy数组的简单方法。
df = pd.DataFrame(somedict)
ytrain = df['label']
ytrain_numpy = np.array([x for x in ytrain['label']])

ytrain_numpy 是一个 NumPy 数组。

我尝试使用 to.numpy(),但是它给了我以下错误:

TypeError: no supported conversion for types: (dtype('O'),)* while doing Binary Relevance classfication using Linear SVC.

to.numpy() 将 DataFrame 转换为 NumPy 数组,但由于内部元素的数据类型是列表,因此出现了上述错误。


我尝试使用 to.numpy(),但是出现以下错误:在使用Linear SVC进行二进制相关性分类时,类型无法转换:(dtype('O'),)。to.numpy() 将 DataFrame 转换为 numpy 数组,但是由于内部元素的数据类型为列表,因此观察到上述错误。不过其实这并不是 to_numpy 的错。 - AMC

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