Pandas系列:Python中的数据结构

136 阅读16分钟

系列数据结构是用来处理Python中的一维数据的。在这篇文章中,我们将讨论如何使用pandas模块创建一个系列,它的属性,以及用实例进行操作。

什么是潘达斯系列?

你可以把Pandas系列看作是一个列表和一个字典的组合。在一个系列中,所有的元素都是按顺序存储的,你可以使用索引来访问它们。

就像我们使用键名访问 python 字典中的值一样,你可以给 pandas 系列中的元素分配标签,并使用标签访问它们。

在Python中创建一个潘达斯系列

为了创建一个系列,我们使用pandas.Series() 函数。它接收一个列表或python字典 作为其输入参数,并返回一个系列。我们已经在下面的章节中讨论了Series() 函数的使用。

将Python列表转换为Pandas系列

你可以使用列表中的元素创建一个潘达斯系列。Series() 方法将列表作为其输入参数,并返回一个系列对象,如下所示。

import pandas as pd
names = ['Aditya', 'Chris', 'Joel']
print("The input list is:")
print(names)
print("The series is:")
mySeries=pd.Series(names)
print(mySeries)

输出。

The input list is:
['Aditya', 'Chris', 'Joel']
The series is:
0    Aditya
1     Chris
2      Joel
dtype: object

在输出中,你可以看到列表中的元素在第二列。系列中的第一列是由系列的索引组成的。指数用于访问系列中的元素。

默认情况下,系列中的索引从0开始。然而,你可以使用Series() 函数中的索引参数明确地将索引分配给系列。

index参数接收一个索引值的列表,并将索引分配给系列中的元素,如下所示。

import pandas as pd
names = ['Aditya', 'Chris', 'Joel']
print("The input list is:")
print(names)
print("The series is:")
mySeries=pd.Series(names, index=["A","B", "C"])
print(mySeries)

输出。

The input list is:
['Aditya', 'Chris', 'Joel']
The series is:
A    Aditya
B     Chris
C      Joel
dtype: object

在这里,我们将列表["A", "B", "C"] 传递给Series() 函数的索引参数。因此,"A"、"B "和 "C "已被分配为系列中各行的索引。

在这里,你需要记住,索引的数量应该等于系列中元素的数量。否则,程序会出现错误,如下图所示。

import pandas as pd
names = ['Aditya', 'Chris', 'Joel']
print("The input list is:")
print(names)
print("The series is:")
mySeries=pd.Series(names, index=["A","B", "C", "D"])
print(mySeries)

输出。

The input list is:
['Aditya', 'Chris', 'Joel']
The series is:

---------------------------------------------------------------------------
ValueError                                Traceback (most recent call last)
/tmp/ipykernel_6004/861141107.py in <module>
      4 print(names)
      5 print("The series is:")
----> 6 mySeries=pd.Series(names, index=["A","B", "C", "D"])
      7 print(mySeries)

ValueError: Length of values (3) does not match length of index (4)

在上面的例子中,我们向索引参数传递了一个包含四个元素的列表。然而,该系列中只有三个元素。因此,程序会遇到ValueError异常。

与其将标签列表传递给Series() 函数,你也可以将标签列表分配给系列的索引属性。这将为系列创建索引标签,如下所示。

import pandas as pd
names = ['Aditya', 'Chris', 'Joel']
print("The input list is:")
print(names)
print("Series before index creation:")
mySeries=pd.Series(names)
print(mySeries)
mySeries.index=["A","B", "C"]
print("Series after index creation:")
print(mySeries)

输出。

The input list is:
['Aditya', 'Chris', 'Joel']
Series before index creation:
0    Aditya
1     Chris
2      Joel
dtype: object
Series after index creation:
A    Aditya
B     Chris
C      Joel
dtype: object

在这个例子中,我们没有使用索引参数,而是使用了系列对象的索引属性来为系列中的行创建索引。

在Python中把Python字典转换为系列

为了制作一个带有标签的pandas系列,你也可以使用一个Python字典。当我们将一个字典传递给Series() 函数时,字典的键就变成了索引标签。一个键所对应的值成为系列中的数据值。你可以在下面的例子中观察到这一点。

import pandas as pd
names = {"A":'Aditya', "B":'Chris', "C":'Joel'}
print("The input dictionary is:")
print(names)
print("The series is:")
mySeries=pd.Series(names)
print(mySeries)

输出。

The input dictionary is:
{'A': 'Aditya', 'B': 'Chris', 'C': 'Joel'}
The series is:
A    Aditya
B     Chris
C      Joel
dtype: object

在上面的例子中,你可以观察到字典中的键已经成为索引标签。字典的相应值被分配到与索引相关的行中。

你也可以将一个元组或其他有序的可迭代对象传递给Series() 函数来创建一个 pandas 系列,而不是一个列表或一个字典。然而,你不能把一个无序的可迭代对象,比如一个集合,作为输入传给Series() 函数来创建一个系列。这样做会使你的程序遇到一个错误,如下图所示。

import pandas as pd
names = {'Aditya', 'Chris', 'Joel'}
print("The input set is:")
print(names)
print("The series is:")
mySeries=pd.Series(names)
print(mySeries)

输出。

The input set is:
{'Joel', 'Aditya', 'Chris'}
The series is:

---------------------------------------------------------------------------
TypeError                                 Traceback (most recent call last)
/tmp/ipykernel_6004/4101083988.py in <module>
      4 print(names)
      5 print("The series is:")
----> 6 mySeries=pd.Series(names)
      7 print(mySeries)

TypeError: 'set' type is unordered

在这里,我们向Series() 函数传递了一个集合。由于这个原因,程序会遇到Python TypeError 异常,并显示集合类型是无序的信息。

Pandas系列中元素的数据类型

当一个系列由列表或字典的元素创建时,系列中元素的数据类型是根据输入元素的数据类型决定的。

例如,如果你把一个整数的列表传递给Series() 函数,结果系列的数据类型将是int64 ,如下所示。

import pandas as pd
names = [1,2,3,4]
print("The input list is:")
print(names)
print("The series is:")
mySeries=pd.Series(names)
print(mySeries)
print("The datatype of series elements is:")
print(mySeries.dtype)

输出。

The input list is:
[1, 2, 3, 4]
The series is:
0    1
1    2
2    3
3    4
dtype: int64
The datatype of series elements is:
int64

上述条件对浮点数也是如此。然而,当我们将一个浮点数和整数的列表传递给Series() 函数时,系列中的结果数据集是float64 ,因为所有的元素都转换为最高级别的兼容数据类型。你可以在下面的例子中观察到这一点。

import pandas as pd
names = [1,2,3.1,4.2]
print("The input list is:")
print(names)
print("The series is:")
mySeries=pd.Series(names)
print(mySeries)
print("The datatype of series elements is:")
print(mySeries.dtype)

输出。

The input list is:
[1, 2, 3.1, 4.2]
The series is:
0    1.0
1    2.0
2    3.1
3    4.2
dtype: float64
The datatype of series elements is:
float64

在上面的例子中,数据类型被写成float64int64 ,因为这些程序是在64位机器上执行的。如果你在32位机器上运行程序,你会得到数据类型为int32和float32。所以,如果你得到这种类型的输出,不用担心。

当你把一个字符串列表传递给Series() 函数时,结果系列元素的数据类型是"object",而不是字符串,如下面的例子中所示。

import pandas as pd
names = ['Aditya', 'Chris', 'Joel']
print("The input list is:")
print(names)
print("The series is:")
mySeries=pd.Series(names)
print(mySeries)
print("The datatype of series elements is:")
print(mySeries.dtype)

输出。

The input list is:
['Aditya', 'Chris', 'Joel']
The series is:
0    Aditya
1     Chris
2      Joel
dtype: object
The datatype of series elements is:
object

当我们将一个包含ints、floats和strings的列表传递给Series() 函数时,系列元素的结果数据类型是 "object"。

import pandas as pd
names = [1, 2.2, 'Joel']
print("The input list is:")
print(names)
print("The series is:")
mySeries=pd.Series(names)
print(mySeries)
print("The datatype of series elements is:")
print(mySeries.dtype)

输出。

The input list is:
[1, 2.2, 'Joel']
The series is:
0       1
1     2.2
2    Joel
dtype: object
The datatype of series elements is:
object

这些元素被分配为对象数据类型,因为我们可以在对象数据类型中包含任何值。将值存储为对象数据类型有助于解释器以简单的方式处理元素的数据类型。

潘达斯系列中的无类型值

在创建系列对象时,当我们将一个包含None值的列表传递给Series() 函数时,会出现一种特殊情况。

当我们将一个包含数值None 的字符串列表传递给Series() 函数时,系列的数据类型是 "object"。这里,值None 被存储为对象类型。

import pandas as pd
names = [1, 2.2, "Aditya", None]
print("The input list is:")
print(names)
print("The series is:")
mySeries=pd.Series(names)
print(mySeries)
print("The datatype of series elements is:")
print(mySeries.dtype)

输出。

The input list is:
[1, 2.2, 'Aditya', None]
The series is:
0         1
1       2.2
2    Aditya
3      None
dtype: object
The datatype of series elements is:
object

然而,当我们传递一个包含值None 的整数列表时,None 被转换为NaN ,这是一个不存在的值的浮点表示。因此,该系列的数据类型变成了float64 。类似地,当我们在一个浮点数列表中传递数值NoneNone 被转换为NaN

import pandas as pd
names = [1, 2.2, 3.2, None]
print("The input list is:")
print(names)
print("The series is:")
mySeries=pd.Series(names)
print(mySeries)
print("The datatype of series elements is:")
print(mySeries.dtype)

输出。

The input list is:
[1, 2.2, 3.2, None]
The series is:
0    1.0
1    2.2
2    3.2
3    NaN
dtype: float64
The datatype of series elements is:
float64

在前面的例子中,None 被存储为NoneType 对象,因为系列包含一个字符串。在这个例子中,None 被存储为浮点值NaN ,因为该系列只包含数字。因此,你可以说 python 解释器根据现有元素的兼容性为系列选择了最佳的数据类型。

当我们将一个包含ints、floats和strings的列表传递给String() 函数时,None 被存储为对象类型。你可以在上面的例子中观察到这一点。

import pandas as pd
names = [1, 2.2, 3.2, None]
print("The input list is:")
print(names)
print("The series is:")
mySeries=pd.Series(names)
print(mySeries)
print("The datatype of series elements is:")
print(mySeries.dtype)

输出。

The input list is:
[1, 2.2, 'Aditya', None]
The series is:
0         1
1       2.2
2    Aditya
3      None
dtype: object
The datatype of series elements is:
object

使用索引操作符从一个系列中访问数据

你可以使用索引操作符从一个系列中访问数据,就像你访问列表元素一样。为此,你可以在索引操作符中传递系列元素的位置,如下所示。

import pandas as pd
names = [1, 2.2, "Aditya", None]
print("The input list is:")
print(names)
print("The series is:")
mySeries=pd.Series(names)
print(mySeries)
index=2
myVal=mySeries[index]
print("Element at index {} is {}".format(index,myVal))

输出。

The input list is:
[1, 2.2, 'Aditya', None]
The series is:
0         1
1       2.2
2    Aditya
3      None
dtype: object
Element at index 2 is Aditya

如果你已经为索引分配了标签,你可以在索引操作符中使用标签来访问系列元素。这类似于我们使用键和索引操作符访问字典的值。

import pandas as pd
names = [1, 2.2, "Aditya", None]
print("The input list is:")
print(names)
print("The series is:")
mySeries=pd.Series(names, index=["A","B", "C", "D"])
print(mySeries)
index="B"
myVal=mySeries[index]
print("Element at index {} is {}".format(index,myVal))

输出。

The input list is:
[1, 2.2, 'Aditya', None]
The series is:
A         1
B       2.2
C    Aditya
D      None
dtype: object
Element at index B is 2.2

在使用索引运算符时,当整数被用作索引标签时,你不能使用元素的位置来访问元素。例如,考虑下面这个例子中的系列。这里,索引标签是整数。因此,我们不能使用索引0来访问系列中的第一个元素,或使用索引1来访问系列中的第二个元素,以此类推。这样做会导致KeyError异常,如下图所示。

import pandas as pd
names = [1, 2.2, "Aditya", None]
print("The input list is:")
print(names)
print("The series is:")
mySeries=pd.Series(names, index=[4,5,6,7])
print(mySeries)
index=0
myVal=mySeries[index]
print("Element at index {} is {}".format(index,myVal))

输出。

The input list is:
[1, 2.2, 'Aditya', None]
The series is:
4         1
5       2.2
6    Aditya
7      None
dtype: object

---------------------------------------------------------------------------
KeyError                                  Traceback (most recent call last)
/tmp/ipykernel_6004/208185265.py in <module>
      7 print(mySeries)
      8 index=0
----> 9 myVal=mySeries[index]
     10 print("Element at index {} is {}".format(index,myVal))

KeyError: 0

因此,在这些情况下,你只能在使用索引运算符访问元素时使用索引标签。然而,你可以使用pandas系列对象的iloc 属性,使用它们在系列中的位置访问元素。

在Python中使用iloc访问系列中的数据

iloc 属性的功能类似于列表索引iloc 属性包含一个_iLocIndexer 对象,你可以用它来访问系列中的数据。你可以简单地使用方括号内的位置与iloc 属性来访问pandas系列的元素,如下所示。

import pandas as pd
names = [1, 2.2, "Aditya", None]
print("The input list is:")
print(names)
print("The series is:")
mySeries=pd.Series(names)
print(mySeries)
position=0
myVal=mySeries.iloc[position]
print("Element at position {} is {}".format(position,myVal))

输出。

The input list is:
[1, 2.2, 'Aditya', None]
The series is:
0         1
1       2.2
2    Aditya
3      None
dtype: object
Element at position 0 is 1

如果你使用整数作为系列的索引标签,这对iloc 属性的工作没有任何影响。iloc 属性是用来访问某个位置的列表的。因此,我们使用什么索引并不重要,iloc 属性的工作方式是一样的。

import pandas as pd
names = [1, 2.2, "Aditya", None]
print("The input list is:")
print(names)
print("The series is:")
mySeries=pd.Series(names,index=[1,2,3,4])
print(mySeries)
position=0
myVal=mySeries.iloc[position]
print("Element at position {} is {}".format(position,myVal))

输出。

The input list is:
[1, 2.2, 'Aditya', None]
The series is:
1         1
2       2.2
3    Aditya
4      None
dtype: object
Element at position 0 is 1

在Python中使用loc属性访问系列中的数据

系列的loc 属性的工作方式与 python 字典的键类似。 loc 属性包含一个_LocIndexer 对象,你可以用它来访问系列中的数据。你可以使用方括号内的索引标签与loc 属性来访问pandas系列的元素,如下所示。

import pandas as pd
names = [1, 2.2, "Aditya", None]
print("The input list is:")
print(names)
print("The series is:")
mySeries=pd.Series(names,index=["A","B","C","D"])
print(mySeries)
index="A"
myVal=mySeries.loc[index]
print("Element at index {} is {}".format(index,myVal))

输出。

The input list is:
[1, 2.2, 'Aditya', None]
The series is:
A         1
B       2.2
C    Aditya
D      None
dtype: object
Element at index A is 1

在潘达斯系列中插入数据

要在一个系列中插入单个元素,你可以使用loc 属性或append() 方法。

要将数据插入带有索引标签的系列中,你可以使用loc 属性。在这里,我们将以在python字典中添加新的键值对的方式,将标签和值分配给系列。

import pandas as pd
names = [1, 2.2, "Aditya", None]
print("The input list is:")
print(names)
print("The series is:")
mySeries=pd.Series(names,index=["A","B","C","D"])
print(mySeries)
index="D"
mySeries.loc[index]=1117
print("The modified series is:")
print(mySeries)

输出。

The input list is:
[1, 2.2, 'Aditya', None]
The series is:
A         1
B       2.2
C    Aditya
D      None
dtype: object
The modified series is:
A         1
B       2.2
C    Aditya
D      1117
dtype: object

append() 方法是用来将一个系列追加到另一个系列。当对一个系列调用时,它将另一个系列作为其输入参数,将其追加到原始系列,并返回一个包含两个系列元素的新系列。

为了在一个系列中插入一个元素,我们将首先用给定的元素创建一个新系列。之后,我们将使用append() 方法将新系列追加到现有系列中,如下例所示。

import pandas as pd
names = [1, 2.2, "Aditya", None]
print("The input list is:")
print(names)
print("The series is:")
mySeries=pd.Series(names,index=["A","B","C","D"])
print(mySeries)
newSeries=pd.Series([1117])
mySeries=mySeries.append(newSeries)
print("The modified series is:")
print(mySeries)

输出。

The input list is:
[1, 2.2, 'Aditya', None]
The series is:
A         1
B       2.2
C    Aditya
D      None
dtype: object
The modified series is:
A         1
B       2.2
C    Aditya
D      None
0      1117
dtype: object

你可以观察到,输出系列的指数并不按顺序排列。这是由于新系列和现有系列的指数已经和元素一起被合并的事实。为了保持指数的顺序,你可以在append() 函数中使用ignore_index=True 参数,如下所示。

import pandas as pd
names = [1, 2.2, "Aditya", None]
print("The input list is:")
print(names)
print("The series is:")
mySeries=pd.Series(names,index=["A","B","C","D"])
print(mySeries)
newSeries=pd.Series([1117])
mySeries=mySeries.append(newSeries, ignore_index=True )
print("The modified series is:")
print(mySeries)

输出。

The input list is:
[1, 2.2, 'Aditya', None]
The series is:
A         1
B       2.2
C    Aditya
D      None
dtype: object
The modified series is:
0         1
1       2.2
2    Aditya
3      None
4      1117
dtype: object

如果现有的系列有索引标签,并且要插入的数据也包含索引的特定标签,你也可以使用append() 方法向系列添加一个新元素,如下图所示。

import pandas as pd
names = [1, 2.2, "Aditya", None]
print("The input list is:")
print(names)
print("The series is:")
mySeries=pd.Series(names,index=["A","B","C","D"])
print(mySeries)
newSeries=pd.Series([1117],index=["P"])
mySeries=mySeries.append(newSeries)
print("The modified series is:")
print(mySeries)

输出。

The input list is:
[1, 2.2, 'Aditya', None]
The series is:
A         1
B       2.2
C    Aditya
D      None
dtype: object
The modified series is:
A         1
B       2.2
C    Aditya
D      None
P      1117
dtype: object

append() 方法已经被废弃,它将在未来的pandas版本中被移除(我目前使用的是pandas 1.4.3)。如果你使用append() 方法并得到错误,可能是你使用的是较新版本的pandas。所以,找一个其他的方法来把元素添加到系列中。

在Python中从潘达斯系列中删除数据

要从Python中的系列中删除数据,你可以使用drop() 方法。drop() 方法,当对一个系列对象调用时,需要一个索引标签或索引标签列表作为其输入参数。执行后,它在删除指定索引处的数据后返回一个新的系列。

要从一个有索引标签的系列中删除一个元素,你可以把索引标签传给drop() ,如下图所示。

import pandas as pd
names = [1, 2.2, "Aditya", None]
print("The series is:")
mySeries=pd.Series(names,index=["A","B","C","D"])
print(mySeries)
mySeries=mySeries.drop("A")
print("The modified series is:")
print(mySeries)

输出。

The series is:
A         1
B       2.2
C    Aditya
D      None
dtype: object
The modified series is:
B       2.2
C    Aditya
D      None
dtype: object

要删除多个索引标签上的元素,你可以向drop() 方法传递一个索引标签的列表,如下图所示。

import pandas as pd
names = [1, 2.2, "Aditya", None]
print("The series is:")
mySeries=pd.Series(names,index=["A","B","C","D"])
print(mySeries)
mySeries=mySeries.drop(["A","D"])
print("The modified series is:")
print(mySeries)

输出。

The series is:
A         1
B       2.2
C    Aditya
D      None
dtype: object
The modified series is:
B       2.2
C    Aditya
dtype: object

在上面的例子中,原始系列没有被修改。要删除原始系列的元素,你可以在drop() 方法中使用inplace=True 参数,如下图所示。

import pandas as pd
names = [1, 2.2, "Aditya", None]
print("The series is:")
mySeries=pd.Series(names,index=["A","B","C","D"])
print(mySeries)
mySeries.drop(["A","D"], inplace=True)
print("The modified series is:")
print(mySeries)

输出。

The series is:
A         1
B       2.2
C    Aditya
D      None
dtype: object
The modified series is:
B       2.2
C    Aditya
dtype: object

要从没有索引标签的系列中删除元素,你可以使用元素在索引处的位置,并将其传递给drop() 方法,如下图所示。

import pandas as pd
names = [1, 2.2, "Aditya", None]
print("The series is:")
mySeries=pd.Series(names)
print(mySeries)
mySeries.drop(0, inplace=True)
print("The modified series is:")
print(mySeries)

输出。

The series is:
0         1
1       2.2
2    Aditya
3      None
dtype: object
The modified series is:
1       2.2
2    Aditya
3      None
dtype: object

要删除多个位置的元素,你可以将索引列表传递给drop() 方法,如下图所示。

import pandas as pd
names = [1, 2.2, "Aditya", None]
print("The series is:")
mySeries=pd.Series(names)
print(mySeries)
mySeries.drop([0,1], inplace=True)
print("The modified series is:")
print(mySeries)

输出。

The series is:
0         1
1       2.2
2    Aditya
3      None
dtype: object
The modified series is:
2    Aditya
3      None
dtype: object

更新潘达斯系列中的数据

为了更新一个给定索引的元素,你可以使用索引操作符与赋值操作符,如下图所示。

import pandas as pd
names = [1, 2.2, "Aditya", None]
print("The series is:")
mySeries=pd.Series(names)
print(mySeries)
mySeries[0]=12345
print("The modified series is:")
print(mySeries)

输出。

The series is:
0         1
1       2.2
2    Aditya
3      None
dtype: object
The modified series is:
0     12345
1       2.2
2    Aditya
3      None
dtype: object

对于一个有索引标签的系列,你可以使用索引标签与赋值运算符,如下图所示。

import pandas as pd
names = [1, 2.2, "Aditya", None]
print("The series is:")
mySeries=pd.Series(names,index=["A","B","C","D"])
print(mySeries)
mySeries["D"]="Chris"
print("The modified series is:")
print(mySeries)

输出。

The series is:
A         1
B       2.2
C    Aditya
D      None
dtype: object
The modified series is:
A         1
B       2.2
C    Aditya
D     Chris
dtype: object

结论

在这篇文章中,我们讨论了如何使用 pandas 模块在 Python 中创建一个系列数据结构。我们还讨论了系列中的索引,如何从系列中删除元素,如何更新系列中的元素,以及如何在系列中插入元素。