使用 numpy 初始化系列对象?

Initializing series object using numpy?

当我从 pandas 开始并试图了解如何使用给定的数组或列表创建系列时,我遇到了这一行...

如果你在 NumPy 的帮助下初始化一个系列对象,那么你只能在其中保存同类数据。

我看不懂它在说什么!我猜 series 可以容纳任何 dtype,只要它在整个特定向量中都相同,不是吗?那么上面一行在这种情况下是什么意思?

这是在这条语句之前写的代码......

import numpy as np
import pandas as pd

labels = ['a','b','c']
my_data = [10,20,30]
arr = np.array(my_data)

print(pd.Series(my_data))
print('==================')
print(pd.Series(my_data,index=labels))
In [550]: labels = ['a','b','c'] 
     ...: my_data = [10,20,30] 
     ...: arr = np.array(my_data)                                                        
In [551]: arr                                                                            
Out[551]: array([10, 20, 30])   # array with `int` dtype

In [553]: pd.Series(my_data)                                                             
Out[553]: 
0    10
1    20
2    30
dtype: int64
In [554]: pd.Series(my_data, index=labels)                                               
Out[554]: 
a    10
b    20
c    30
dtype: int64

注意 dtype

混合了 int 和字符串的列表:

In [555]: alist = [10,'twenty',30]                                                       
In [556]: pd.Series(alist, index=labels)                                                 
Out[556]: 
a        10
b    twenty
c        30
dtype: object

注意 dtype 的变化

从该列表创建数组 - 注意字符串数据类型:

In [557]: np.array(alist)                                                                
Out[557]: array(['10', 'twenty', '30'], dtype='<U21')
In [558]: pd.Series(np.array(alist), index=labels)                                       
Out[558]: 
a        10
b    twenty
c        30
dtype: object
In [559]: _.to_numpy()                                                                   
Out[559]: array(['10', 'twenty', '30'], dtype=object)

[558] 看起来与 [556] 相同,但 10,20 不同 - 一个是整数,另一个是字符串。无论好坏,pandas 显示相同的字符串和数字。

当您有 my_data 非同质 项时,例如数字的混合 和字符串,例如:

labels = ['a', 'b', 'c', 'd', 'e']
my_data = [10, 20, 30, 'xx', 12.55]
arr = np.array(my_data)
s = pd.Series(my_data, index=labels)

并打印arr,你会得到:

array(['10', '20', '30', 'xx', '12.55'], dtype='<U11')

注意 arr 中的每一项都是一个 string.

乍一看,s也是如此。当你打印它时,你会得到:

a       10
b       20
c       30
d       xx
e    12.55
dtype: object

当你看物品本身时,它们的类型并不明显,但看 在底线:dtype: object。 第一个想到的是"actually a string",其实就是这个意思 "it depends from particular cell".

要确认这一点,请查看单个单元格:

type(s['a']) 产生 inttype(s['d']) 产生 strtype(s['e']) 产生 float(每个都是 object 的后代)。

现在尝试 同质 变体:

my_data = [10, 20, 30, 4.12, 12.55]

intfloat,其他 "initial" 指令如上)。

现在当你打印 arr 时,你将得到:

array([10.  , 20.  , 30.  ,  4.12, 12.55])

所以所有元素都被强制到最近的可能祖先,在这个 案例只是 float.

当你打印s时,结果是:

a    10.00
b    20.00
c    30.00
d     4.12
e    12.55
dtype: float64

所以它的类型继承自arr.

这次,当您打印 type(s['a']) (或任何其他单元格)时, 你会得到 float.

还要注意普通 pythonic 列表和 Numpy 数组之间的差异:

  • 列表中每个元素都有自己的类型,
  • Numpy 数组中,类型被分配给 array,即 它的所有元素都具有相同的类型(尽管它们可以是 subtypes 整个数组的 "basic" 类型)。

因此,当您从 Numpy 数组(一维或二维 分别):

  • 系列对象从源数组继承类型,
  • DataFrame 的每一列也从该数组继承类型。

当然,您也可以从多个单独的一维数据集创建一个 DataFrame Numpy 数组(列的来源),每个都有自己的类型和 生成的 DataFrame 也将继承源类型,分别 对于每一列,来自各自的 Numpy 数组。

根据问题进行编辑

直到 Pandas 版本 1.0 才引入了一些 新的、实验性的数据类型,其中包括 string(正是您所要求的)。

显然 Pandas 作者认识到需要 "explicit" 字符串,而不是 "any object, maybe a string".

但这些变化是逐步引入的,目前不包括现有的 从文件中读取内容的方法。 例如。 read_csv 操作 "the old way",即如果某列是 非数字和非类日期类型,则假定 object 类型。

要允许将此类列转换为 "new" dtypes,convert_dtypes() 添加了方法,例如调用在 read_csv 之后,尝试 将每列的类型更改为某些 "new" dtypes(如果可能)。

要更完整地了解最近添加的内容及其使用方法, 阅读有关新数据类型 Pandas 的文档,NA 标量和 处理缺失数据。