【pandas官方文档-用户指南】2.数据结构简介

2022/5/27 23:19:26

本文主要是介绍【pandas官方文档-用户指南】2.数据结构简介,对大家解决编程问题具有一定的参考价值,需要的程序猿们随着小编来一起学习吧!

2.数据结构简介

本节要点:

  • 数据类型、索引和轴标签/对齐的基本行为
import pandas as pd
import numpy as np

请记住一个基本原则:数据对齐是固有的。除非您明确地这样做,否则标签和数据之间的链接不会断开。

2.1.Series

Series是一个一维标签数组,能够保存任何数据类型(整数、字符串、浮点数、Python对象等)。轴标签统称为索引。

创建Series的基本方法是调用:

s = pd.Series(data, index=index)
---------------------------------------------------------------------------

NameError                                 Traceback (most recent call last)

/Users/watalo/programs/pandas-note/scripts/用户指南/02-数据结构简介.ipynb Cell 4' in <cell line: 1>()
----> <a href='vscode-notebook-cell:/Users/watalo/programs/pandas-note/scripts/%E7%94%A8%E6%88%B7%E6%8C%87%E5%8D%97/02-%E6%95%B0%E6%8D%AE%E7%BB%93%E6%9E%84%E7%AE%80%E4%BB%8B.ipynb#ch0000003?line=0'>1</a> s = pd.Series(data, index=index)


NameError: name 'data' is not defined

data,可以有很多种:

  • Python字典
  • ndarray
  • 标量值(scalar value)

index,轴标签列表。可以分几种情况:

  • From ndarray
  • From dict
  • From scalar value

From ndarray

s = pd.Series(np.random.randn(5),index=['a', 'b','c','d','e'])
s
a    0.883299
b   -1.978170
c    0.563257
d   -0.797373
e    0.776716
dtype: float64
s.index
Index(['a', 'b', 'c', 'd', 'e'], dtype='object')

Note:

  • pandas支持非唯一索引值。如果试图执行不支持重复索引值的操作,将会引发异常。原因主要是基于性能的考虑(在计算中有许多实例,比如GroupBy的某些部分,其中不使用索引)。

From dict

Series可以直接从字典实例化

d = {
    'a':1,
    'b':2,
    'c':3,
}

s = pd.Series(d)
s
a    1
b    2
c    3
dtype: int64

当数据是dict,并且没有传递索引时,如果您使用的是Python版本> = 3.6和pandas版本> = 0.23,系列索引将按照dict的插入顺序排序。

如果您使用的是Python < 3.6或pandas < 0.23,并且没有传递索引,那么系列索引将是字典键的词汇排序列表。

如果传递了一个索引,则对应于索引中标签的数据中的值将被取出。

s = pd.Series(d, index=['e','d','c','b','a'])
s
e    NaN
d    NaN
c    3.0
b    2.0
a    1.0
dtype: float64

From scalar value

如果数据是标量值,则必须提供索引。该值将重复以匹配索引的长度。

s = pd.Series(5, index=['1','2','3','4','5','6'])
s.index
Index(['1', '2', '3', '4', '5', '6'], dtype='object')

Series 与多维数组相似

Series的行为非常类似于ndarray,并且是大多数NumPy函数的有效参数。但是,切片等操作也会对索引进行切片。

s[0]
0.8832993937192529
s[:3]
a    0.883299
b   -1.978170
c    0.563257
dtype: float64
s[s > s.median()]
a    0.883299
e    0.776716
dtype: float64
s[[3,1]]
d   -0.797373
b   -1.978170
dtype: float64
np.exp(s) # e^s 自然数的幂
a    2.418867
b    0.138322
c    1.756384
d    0.450511
e    2.174320
dtype: float64
s.dtype
dtype('float64')

这是Numpy的数据类型。然而,pandas和第三方库在一些地方扩展了NumPy的类型系统,在这种情况下,dtype将是ExtensionDtype。pandas中的一些例子是分类数据和可空整数数据类型。有关更多信息,请参见dtypes。

如果您需要获取一个Series的实际数组,请使用Series.array。

s.array
<PandasArray>
[ 0.8832993937192529,  -1.978169783141144,   0.563257208682096,
 -0.7973732860782697,  0.7767158700697264]
Length: 5, dtype: float64

当您需要在没有索引的情况下执行某些操作时(例如,禁用自动对齐),访问数组会很有用。

Series.array将始终是ExtensionArray。简而言之,ExtensionArray是一个或多个具体数组(如numpy.ndarray)的简单包装。pandas知道如何获取ExtensionArray并将其存储在数据帧的一个系列或一列中。有关更多信息,请参见dtypes。

虽然Series类似于ndarray,但如果需要实际的ndarray,则使用Series.to_numpy()。

s.to_numpy()
array([ 0.88329939, -1.97816978,  0.56325721, -0.79737329,  0.77671587])

即使序列是ExtensionArray类型的,Series.to_numpy()也将返回NumPy ndarray。

Series 与字典相似

系列类似于固定大小的字典,因为您可以通过索引标签获取和设置值:

s['a']
0.8832993937192529
s['f'] = 12.0
s
a     0.883299
b    -1.978170
c     0.563257
d    -0.797373
e     0.776716
f    12.000000
dtype: float64
'e' in s
True
'g' in s
False
s.get('s')

使用get方法,缺少的标签将返回None或指定的默认值:

s.get('s', np.nan)
nan

矢量化运算和标签序列对齐

当处理原始NumPy数组时,通常没有必要逐值循环。在pandas中处理系列时也是如此。Series也可以传递给大多数需要ndarray的NumPy方法。

s+s
a     1.766599
b    -3.956340
c     1.126514
d    -1.594747
e     1.553432
f    24.000000
dtype: float64
s *2
a     1.766599
b    -3.956340
c     1.126514
d    -1.594747
e     1.553432
f    24.000000
dtype: float64
np.exp(s)
a         2.418867
b         0.138322
c         1.756384
d         0.450511
e         2.174320
f    162754.791419
dtype: float64

Series和ndarray之间的一个关键区别是,Series之间的操作会根据标签自动对齐数据。因此,您可以在编写计算时不考虑所涉及的系列是否具有相同的标签。

s[1:] + s[:-1]
a         NaN
b   -3.956340
c    1.126514
d   -1.594747
e    1.553432
f         NaN
dtype: float64
(s[1:] + s[:-1]).dropna()
b   -3.956340
c    1.126514
d   -1.594747
e    1.553432
dtype: float64

未对齐系列之间的运算结果将包含相关索引的并集。如果在一个系列或另一个系列中找不到标签,结果将被标记为缺少NaN。能够在不进行任何显式数据对齐的情况下编写代码,这为交互式数据分析和研究提供了极大的自由和灵活性。pandas数据结构的集成数据对齐特性使pandas有别于大多数处理标注数据的相关工具。

注意:

一般来说,我们选择让不同索引对象之间的默认操作结果产生索引的联合,以避免信息丢失。尽管缺少数据,但作为计算的一部分,具有索引标签通> 常是重要的信息。当然,您可以选择通过dropna函数删除带有缺失数据的标签。

名称属性

系列也可以有名称属性:

ss = pd.Series(np.random.randn(5), name = 'Something')
ss
0    0.854195
1   -2.466692
2   -1.145952
3   -0.192568
4    0.160081
Name: Something, dtype: float64

在许多情况下,将自动分配系列名称,尤其是在处理DataFrame的一维切片时,如下所示。

你可以给Series重新命名。Series.rename()方法。

s2 = ss.rename('nothing')
s2.name
'nothing'

2.2.DataFrame

DataFrame是每列数据带有潜在不同类型的二维标记数据结构。你可以把它想象成一个电子表格或SQL表,或者一系列对象的字典。它是pandas最常用的对象。像Series一样,DataFrame接受许多不同类型的输入:

  • 一维字典,清单,字典或系列
  • 二维数字阵列
  • 结构化或记录阵列
  • 一个Series
  • 另一个DataFrame

除了数据,您还可以选择传递索引(行标签)和列(列标签)参数。如果您传递一个索引和/或列,您就保证了结果数据帧的索引和/或列。因此,一个系列字典加上一个特定的索引将丢弃所有与传递的索引不匹配的数据。

如果没有传递轴标签,它们将根据常识规则从输入数据中构建。(0,1,2,3,4,5)

注意:

当数据是一个dict,并且没有指定columns时,如果您使用的是Python版本> = 3.6和pandas >= 0.23,DataFrame列将按dict的插入顺序排序。

如果您使用的是Python < 3.6或pandas < 0.23,并且没有指定columns,DataFrame列将是字典键的词汇排序列表。

From 序列或字典的字典

生成的索引将是各种系列指数的联合。如果有任何嵌套的字典,它们将首先被转换成序列。如果没有传递任何列,这些列将是dict键的有序列表。

d = {
    'one': pd.Series([1.0,2.0,3.0], index=['a','b','c']),
    'two': pd.Series([1.0,2.0,3.0,4.0], index=['a','b','c','d']),
}

df = pd.DataFrame(d)
df
one two
a 1.0 1.0
b 2.0 2.0
c 3.0 3.0
d NaN 4.0
pd.DataFrame(d, index=['a','b','c'])
one two
a 1.0 1.0
b 2.0 2.0
c 3.0 3.0
pd.DataFrame(d, index=["d", "b", "a"], columns=["two", "three"])
two three
d 4.0 NaN
b 2.0 NaN
a 1.0 NaN

通过访问索引和列属性,可以分别访问行标签和列标签:

注意

当一组特定的列和一个数据字典一起传递时,传递的列会覆盖字典中的键。

df.index
Index(['a', 'b', 'c', 'd'], dtype='object')
df.columns
Index(['one', 'two'], dtype='object')

From多维数组或列表的字典

多维数组的长度必须相同。如果传递一个索引,它显然也必须与数组的长度相同。如果没有传递索引,结果将是range(n),其中n是数组长度。

d = {"one": [1.0, 2.0, 3.0, 4.0], "two": [4.0, 3.0, 2.0, 1.0]}

pd.DataFrame(d)
one two
0 1.0 4.0
1 2.0 3.0
2 3.0 2.0
3 4.0 1.0
pd.DataFrame(d, index=list('abcd'))
one two
a 1.0 4.0
b 2.0 3.0
c 3.0 2.0
d 4.0 1.0

From结构化或记录数组

这种情况的处理方式与数组字典相同。

data = np.zeros((2,),dtype = [("A", "i4"),("B", "f4"),("C", "a10")])
data[:] = [(1, 2.0, "Hello"),(2, 3.0, "World")]
pd.DataFrame(data)
A B C
0 1 2.0 b'Hello'
1 2 3.0 b'World'
pd.DataFrame(data, index=['first','second'])
A B C
first 1 2.0 b'Hello'
second 2 3.0 b'World'
pd.DataFrame(data, columns=['C', "A","B"])
C A B
0 b'Hello' 1 2.0
1 b'World' 2 3.0

注意:

DataFrame的工作方式并不完全像二维NumPy ndarray。

From字典的列表

data2 = [{"a": 1, "b": 2}, {"a": 5, "b": 10, "c": 20}]
pd.DataFrame(data2)
a b c
0 1 2 NaN
1 5 10 20.0
pd.DataFrame(data2, index=["first", "second"])
a b c
first 1 2 NaN
second 5 10 20.0
pd.DataFrame(data2, columns=["a", "b"])
a b
0 1 2
1 5 10

From元组字典

通过传递元组字典,可以自动创建多索引框架。

pd.DataFrame(
    {
        ("a", "b"): {("A", "B"): 1, ("A", "C"): 2},
        ("a", "a"): {("A", "C"): 3, ("A", "B"): 4},
        ("a", "c"): {("B", "B"): 5, ("A", "C"): 6},
        ("b", "a"): {("B", "C"): 7, ("A", "B"): 8},
        ("b", "b"): {("A", "D"): 9, ("A", "B"): 10},
    }
)
a b
b a c a b
A B 1.0 4.0 NaN 8.0 10.0
C 2.0 3.0 6.0 NaN NaN
B B NaN NaN 5.0 NaN NaN
C NaN NaN NaN 7.0 NaN
A D NaN NaN NaN NaN 9.0

From一个系列

结果将是一个DataFrame,其索引与输入序列相同,并且有一个列的名称是序列的原始名称(仅当没有提供其他列名称时)。

From命名元组列表

列表中第一个命名元组的字段名称决定了DataFrame的列。剩余的命名元组(或元组)被简单地解包,并且它们的值被赋值到数据帧的行中。如果这些元组中的任何一个比第一个命名元组短,则相应行中后面的列将被标记为缺失值。如果有任何长度超过第一个命名的元组,将引发ValueError。

from collections import namedtuple
Point = namedtuple("Point",'x y')
pd.DataFrame([Point(0, 0),Point(0,2),(2,3)])
x y
0 0 0
1 0 2
2 2 3
Point3D = namedtuple("Point3D",'x y z')
pd.DataFrame([Point3D(0,0,0),Point3D(0,3,5),Point(0,2)])
x y z
0 0 0 0.0
1 0 3 5.0
2 0 2 NaN

From数据类

版本1.1.0中的新增功能。

PEP557中介绍的数据类可以传递给DataFrame构造函数。传递数据类列表相当于传递字典列表。

请注意,列表中的所有值都应该是数据类,混合列表中的类型会导致类型错误。

from dataclasses import make_dataclass

Point = make_dataclass("Point", [("x", int), ("y", int)])

pd.DataFrame([Point(0, 0), Point(0, 3), Point(2, 3)])
x y
0 0 0
1 0 3
2 2 3

缺失数据

关于这个主题,我们将在“缺失数据”部分详细讨论。为了构造一个带有缺失数据的DataFrame,我们使用np.nan来表示缺失值。或者,你可以通过一个numpy.MaskedArray作为DataFrame构造函数的数据参数,其被屏蔽的条目将被视为丢失。

备选构造函数

DataFrame.from_dict

DataFrame.from_dict接受一个dict或一个类似数组的序列的dict,并返回一个DataFrame。除了orient参数之外,它的操作与DataFrame构造函数类似,orient参数默认为“columns ”,但可以设置为“index ”,以便将dict键用作行标签。

pd.DataFrame.from_dict(dict([("A", [1, 2, 3]), ("B", [4, 5, 6])]))
A B
0 1 4
1 2 5
2 3 6

如果传递orient='index ',则键将是行标签。在这种情况下,您还可以传递所需的列名:

pd.DataFrame.from_dict(
    dict([("A", [1, 2, 3]), ("B", [4, 5, 6])]),
    orient="index",
    columns=["one", "two", "three"],
)
one two three
A 1 2 3
B 4 5 6

DataFrame.from _records

DataFrame.from_records采用元组列表或具有结构化数据类型的ndarray。它的工作方式类似于普通的DataFrame构造函数,只是产生的DataFrame索引可能是结构化数据类型的特定字段。例如:

from_dicts, from_records这两个函数不知道什么意义。

列选择、添加、删除

您可以将DataFrame在语义上视为相似索引系列对象的字典。获取、设置和删除列的语法与类似的dict操作相同:

d = {
    'one': pd.Series([1,2,3],index=list('abc')),
    'two': pd.Series([1,2,3,4],index=list('abcd'))
}
df =pd.DataFrame(d)
df
one two
a 1.0 1
b 2.0 2
c 3.0 3
d NaN 4
df['one']
a    1.0
b    2.0
c    3.0
d    NaN
Name: one, dtype: float64
df['three'] = df['one']*df['two']
df['three']
a    1.0
b    4.0
c    9.0
d    NaN
Name: three, dtype: float64
df['flag'] = df['two'] > 2
df['flag']
a    False
b    False
c     True
d     True
Name: flag, dtype: bool

可以像使用字典一样删除或弹出列:

del df['two']
df.pop('three')
df
one flag
a 1.0 False
b 2.0 False
c 3.0 True
d NaN True

当插入标量值时,它将自然地传播(繁殖)以填充列:

df['foo'] = 'bar'
df
one flag foo
a 1.0 False bar
b 2.0 False bar
c 3.0 True bar
d NaN True bar

当插入与DataFrame没有相同索引的序列时,它将符合DataFrame的索引:

df['one_trunc']= df['one'][:2]
df
one flag foo one_trunc
a 1.0 False bar 1.0
b 2.0 False bar 2.0
c 3.0 True bar NaN
d NaN True bar NaN

您可以插入原始ndarrays,但它们的长度必须与DataFarme索引的长度相匹配。

raw ndarrays:是不是构造Series的ndarrays? 而Series在DataFrame中就是列,所以索引必须保持一致。
注意:Series在DataFrame中不是row的概念,而是与索引对应的。

默认情况下,列在末尾插入。插入功能可用于在列中的特定位置插入:

df.insert(1, 'bar', df['one'])
df
one bar flag foo one_trunc
a 1.0 1.0 False bar 1.0
b 2.0 2.0 False bar 2.0
c 3.0 3.0 True bar NaN
d NaN NaN True bar NaN
array = df['one'].to_numpy() array
array([ 1.,  2.,  3., nan])
df.insert(1,'one_array',array)
df
one one_array bar flag foo one_trunc
a 1.0 1.0 1.0 False bar 1.0
b 2.0 2.0 2.0 False bar 2.0
c 3.0 3.0 3.0 True bar NaN
d NaN NaN NaN True bar NaN

在方法链中分配新列

DataFrame.assign()方法,允许您能轻松地从现有列派生新列。

iris = pd.read_csv("./data/iris.csv") # 这些数据没有直接提供,但是可以使用sklearn库获得,见irisdata.py
iris.head()
Unnamed: 0 sepal length (cm) sepal width (cm) petal length (cm) petal width (cm) outcome
0 0 5.1 3.5 1.4 0.2 0
1 1 4.9 3.0 1.4 0.2 0
2 2 4.7 3.2 1.3 0.2 0
3 3 4.6 3.1 1.5 0.2 0
4 4 5.0 3.6 1.4 0.2 0
iris.columns # 数据下载后有点不一样,做一些处理
iris.pop('Unnamed: 0')
iris= iris.rename(columns={
    "sepal length (cm)": "Sepallength",
    "sepal width (cm)":"Sepalwidth",
    "petal length (cm)":"Petallength",
    "petal width (cm)":"Petalwidth",
})
iris
Sepallength Sepalwidth Petallength Petalwidth outcome
0 5.1 3.5 1.4 0.2 0
1 4.9 3.0 1.4 0.2 0
2 4.7 3.2 1.3 0.2 0
3 4.6 3.1 1.5 0.2 0
4 5.0 3.6 1.4 0.2 0
... ... ... ... ... ...
145 6.7 3.0 5.2 2.3 2
146 6.3 2.5 5.0 1.9 2
147 6.5 3.0 5.2 2.0 2
148 6.2 3.4 5.4 2.3 2
149 5.9 3.0 5.1 1.8 2

150 rows × 5 columns

assign总是返回数据的副本,而不改变原始数据帧。

当您手头没有对DataFrame的引用时,传递一个callable(而不是要插入的实际值)非常有用。在操作链中使用赋值时,这很常见。例如,我们可以将数据框限制为萼片长度大于5的观察值,计算比率,并绘制:

(
    iris.query("Sepallength > 5")   # 与官方案例中的命名有点点区别,都相应做了些调整
    .assign(
        SepalRatio=lambda x: x.Sepalwidth / x.Sepallength,
        PetalRatio=lambda x: x.Petalwidth / x.Petallength,
    )
    .plot(kind="scatter", x="SepalRatio", y="PetalRatio")
)
<AxesSubplot:xlabel='SepalRatio', ylabel='PetalRatio'>

因为函数是传入的,所以函数是在被赋值的DataFrame上计算的。重要的是,这是已经被过滤成萼片长度大于5的那些行的DataFrame。首先进行过滤,然后进行比率计算。这是一个我们没有可用的过滤数据帧参考的例子。

用于赋值的函数符号就是**kwargs。键是新字段的列名,值或者是要插入的值(例如,Series或NumPy数组),或者是要在DataFrame上调用的一个参数的函数。返回原始DataFrame的副本,并插入新值。

从Python 3.6开始,保留了kwargs的顺序。这允许依赖赋值,其中kwargs中后面的表达式可以引用同一个assign()中前面创建的列。

dfa = pd.DataFrame({"A": [1, 2, 3], "B": [4, 5, 6]})
dfa.assign(C = lambda x: x['A']+x['B'], D = lambda x: x['C']+x['B'])
A B C D
0 1 4 5 9
1 2 5 7 12
2 3 6 9 15

在第二个表达式中,x['C']将引用新创建的列,等于dfa['A'] + dfa['B']

索引和选择

索引的基本语法如下:

操作 语法 结果
选择列 df[col] Series
选择行,按标签 df.loc[label] Series
选择行,按位置 df.iloc[loc] Series
行切片 df[5:10] DataFrame
选择行,按布尔向量 df[bool_vec] DataFrame

例如,行选择返回一个系列,其索引是数据帧的列:

df.loc['b']
one            2.0
bar            2.0
flag         False
foo            bar
one_trunc      2.0
Name: b, dtype: object
df.iloc[2]
one           3.0
bar           3.0
flag         True
foo           bar
one_trunc     NaN
Name: c, dtype: object

有关复杂的基于标签的索引和切片的更详尽的论述,请参阅索引一节。我们将在重建索引一节中讨论重建索引/符合新标签集的基础知识。

数据对齐和算术

DataFrame对象之间的数据对齐在列和索引(行标签)上自动对齐。同样,结果对象将具有列和行标签的联合。

df = pd.DataFrame(np.random.randn(10, 4), columns=["A", "B", "C", "D"])
df2 = pd.DataFrame(np.random.randn(7, 3), columns=["A", "B", "C"])
df + df2
A B C D
0 0.791989 1.341828 -1.053359 NaN
1 -2.860043 -0.651756 0.968590 NaN
2 0.302202 0.969432 2.437236 NaN
3 0.041251 -0.674415 -1.176100 NaN
4 1.280775 -3.399843 -0.261751 NaN
5 -0.461997 0.362092 -1.414859 NaN
6 -0.673482 0.729642 -0.105722 NaN
7 NaN NaN NaN NaN
8 NaN NaN NaN NaN
9 NaN NaN NaN NaN

在DataFrame和Series之间执行操作时,默认行为是对齐DataFrame列上的Series索引,从而按行扩充。例如:

df - df.iloc[0]
A B C D
0 0.000000 0.000000 0.000000 0.000000
1 -0.259708 -1.257956 0.955413 0.560935
2 0.810066 0.324911 0.091001 0.314986
3 0.947707 -1.684121 -1.993186 -0.596684
4 0.541464 -2.169467 -1.123502 1.075880
5 0.549983 -0.153812 -1.049392 0.629938
6 0.088894 0.149594 -0.015635 -0.086467
7 0.872696 -2.982769 1.441553 0.484981
8 0.849373 -1.689104 -2.110944 -0.674473
9 0.605957 -0.396698 -1.618992 1.284446

对于匹配和广播行为的显式控制,请参见灵活二进制操作一节。

标量操作正如您所料:

df * 5 + 2
A B C D
0 1.323638 6.561460 3.348269 -0.735045
1 0.025100 0.271678 8.125334 2.069632
2 5.373969 8.186013 3.803276 0.839885
3 6.062174 -1.859145 -6.617663 -3.718466
4 4.030958 -4.285874 -2.269242 4.644356
5 4.073552 5.792401 -1.898691 2.414645
6 1.768109 7.309428 3.270094 -1.167379
7 5.687115 -8.352386 10.556034 1.689860
8 5.570503 -1.884063 -7.206450 -4.107409
9 4.353421 4.577971 -4.746690 5.687187
1/df
A B C D
0 -7.392487 1.096140 3.708458 -1.828124
1 -2.531773 -2.892979 0.816282 71.806529
2 1.481934 0.808275 2.772731 -4.309916
3 1.230868 -1.295624 -0.580204 -0.874360
4 2.461892 -0.795434 -1.171168 1.890820
5 2.411322 1.318426 -1.282482 12.058512
6 -21.561889 0.941721 3.936717 -1.578592
7 1.356074 -0.482980 0.584383 -16.121743
8 1.400363 -1.287312 -0.543098 -0.818678
9 2.124567 1.939510 -0.741104 1.356047
df ** 4
A B C D
0 0.000335 0.692684 0.005287 8.953187e-02
1 0.024339 0.014276 2.252367 3.761355e-08
2 0.207341 2.342952 0.016919 2.898175e-03
3 0.435666 0.354882 8.824253 1.710954e+00
4 0.027222 2.497943 0.531524 7.823474e-02
5 0.029579 0.330961 0.369654 4.729607e-05
6 0.000005 1.271484 0.004164 1.610350e-01
7 0.295711 18.377304 8.574522 1.480308e-05
8 0.260039 0.364137 11.494463 2.226118e+00
9 0.049082 0.070669 3.314996 2.957336e-01

布尔运算符也起作用:

df1 = pd.DataFrame({"a": [1, 0, 1], "b": [0, 1, 1]}, dtype=bool)

df2 = pd.DataFrame({"a": [0, 1, 1], "b": [1, 1, 0]}, dtype=bool)

df1 & df2
a b
0 False False
1 False True
2 True False
df1 | df2
a b
0 True True
1 True True
2 True True
df1 ^ df2
a b
0 True True
1 True False
2 False True
-df1
a b
0 False True
1 True False
2 False False

转置

要转置,访问T属性(也是转置函数),类似于ndarray:

df[:5].T
0 1 2 3 4
A -0.135272 -0.394980 0.674794 0.812435 0.406192
B 0.912292 -0.345664 1.237203 -0.771829 -1.257175
C 0.269654 1.225067 0.360655 -1.723533 -0.853848
D -0.547009 0.013926 -0.232023 -1.143693 0.528871

DataFrame与NumPy函数的互操作性

Elementwise NumPy ufuncs (log、exp、sqrt、…)和各种其他NumPy函数可以在Series和DataFrame上使用,不会出现任何问题,前提是其中的数据是数字:

np.exp(df)
A B C D
0 0.873478 2.490023 1.309511 0.578678
1 0.673693 0.707750 3.404394 1.014024
2 1.963628 3.445960 1.434269 0.792928
3 2.253388 0.462167 0.178435 0.318640
4 1.501090 0.284457 0.425773 1.697016
5 1.513932 2.135029 0.458526 1.086465
6 0.954681 2.891819 1.289196 0.530744
7 2.090541 0.126126 5.535637 0.939857
8 2.042349 0.459869 0.158613 0.294793
9 1.601089 1.674633 0.259412 2.090571
np.asarray(df)
array([[-0.13527247,  0.91229194,  0.26965386, -0.54700892],
       [-0.39498006, -0.34566449,  1.22506688,  0.01392631],
       [ 0.67479376,  1.23720267,  0.36065521, -0.23202306],
       [ 0.81243481, -0.77182897, -1.72353255, -1.14369325],
       [ 0.4061916 , -1.25717476, -0.85384845,  0.5288712 ],
       [ 0.41471035,  0.75848022, -0.77973825,  0.08292897],
       [-0.04637813,  1.06188561,  0.25401878, -0.63347584],
       [ 0.73742305, -2.07047719,  1.71120672, -0.06202803],
       [ 0.7141007 , -0.77681254, -1.84128991, -1.22148186],
       [ 0.47068421,  0.51559416, -1.34933804,  0.7374374 ]])

DataFrame不是ndarray的替代品,因为它的索引语义和数据模型与n维数组有很大不同。

Series实现了__array_ufunc__,这允许它与NumPy的通用函数一起工作。

ufunc应用于系列中的基础数组。

ser = pd.Series([1,2,3,4])
np.exp(ser)
0     2.718282
1     7.389056
2    20.085537
3    54.598150
dtype: float64

像库的其他部分一样,pandas将自动对齐带标签的输入,作为具有多个输入的ufunc的一部分。例如,对具有不同排序标签的两个系列使用numpy.remainder()将在操作之前对齐。

ser1 = pd.Series([1, 2, 3], index=["a", "b", "c"])
ser2 = pd.Series([1, 3, 5], index=["b", "a", "c"])
ser1, ser2
(a    1
 b    2
 c    3
 dtype: int64,
 b    1
 a    3
 c    5
 dtype: int64)
np.remainder(ser1, ser2)
a    1
b    0
c    3
dtype: int64

像往常一样,取两个索引的并集,用缺失值填充不重叠的值。

ser3 = pd.Series([2, 4, 6], index=["b", "c", "d"])
ser3
b    2
c    4
d    6
dtype: int64
np.remainder(ser1, ser3)
a    NaN
b    0.0
c    3.0
d    NaN
dtype: float64

当二进制ufunc应用于序列和索引时,序列实现优先,并返回一个序列。

ser = pd.Series([1, 2, 3])
idx = pd.Index([4, 5, 6])
np.maximum(ser, idx)
0    4
1    5
2    6
dtype: int64

NumPy ufuncs可以安全地应用于非ndarray数组支持的系列,例如arrays.SparseArray(请参见Sparse calculation)。如果可能,在不将基础数据转换为ndarray的情况下应用ufunc。

控制台显示器

非常大的DataFrame将被截断以显示在控制台中。您还可以使用info()获得摘要。(这里我正在阅读来自plyr R包的棒球数据集的CSV版本):

baseball = pd.read_csv("./data/baseball.csv")
print(baseball)
       Unnamed: 0         id  year  stint team   lg    g   ab   r    h  ...  \
0               4  ansonca01  1871      1  RC1  NaN   25  120  29   39  ...   
1              44  forceda01  1871      1  WS3  NaN   32  162  45   45  ...   
2              68  mathebo01  1871      1  FW1  NaN   19   89  15   24  ...   
3              99  startjo01  1871      1  NY2  NaN   33  161  35   58  ...   
4             102  suttoez01  1871      1  CL1  NaN   29  128  35   45  ...   
...           ...        ...   ...    ...  ...  ...  ...  ...  ..  ...  ...   
21694       89525  benitar01  2007      2  FLO   NL   34    0   0    0  ...   
21695       89526  benitar01  2007      1  SFN   NL   19    0   0    0  ...   
21696       89530  ausmubr01  2007      1  HOU   NL  117  349  38   82  ...   
21697       89533   aloumo01  2007      1  NYN   NL   87  328  51  112  ...   
21698       89534  alomasa02  2007      1  NYN   NL    8   22   1    3  ...   

        rbi   sb   cs  bb    so  ibb  hbp   sh   sf  gidp  
0      16.0  6.0  2.0   2   1.0  NaN  NaN  NaN  NaN   NaN  
1      29.0  8.0  0.0   4   0.0  NaN  NaN  NaN  NaN   NaN  
2      10.0  2.0  1.0   2   0.0  NaN  NaN  NaN  NaN   NaN  
3      34.0  4.0  2.0   3   0.0  NaN  NaN  NaN  NaN   NaN  
4      23.0  3.0  1.0   1   0.0  NaN  NaN  NaN  NaN   NaN  
...     ...  ...  ...  ..   ...  ...  ...  ...  ...   ...  
21694   0.0  0.0  0.0   0   0.0  0.0  0.0  0.0  0.0   0.0  
21695   0.0  0.0  0.0   0   0.0  0.0  0.0  0.0  0.0   0.0  
21696  25.0  6.0  1.0  37  74.0  3.0  6.0  4.0  1.0  11.0  
21697  49.0  3.0  0.0  27  30.0  5.0  2.0  0.0  3.0  13.0  
21698   0.0  0.0  0.0   0   3.0  0.0  0.0  0.0  0.0   0.0  

[21699 rows x 23 columns]
baseball.info()
<class 'pandas.core.frame.DataFrame'>
RangeIndex: 21699 entries, 0 to 21698
Data columns (total 23 columns):
 #   Column      Non-Null Count  Dtype  
---  ------      --------------  -----  
 0   Unnamed: 0  21699 non-null  int64  
 1   id          21699 non-null  object 
 2   year        21699 non-null  int64  
 3   stint       21699 non-null  int64  
 4   team        21699 non-null  object 
 5   lg          21634 non-null  object 
 6   g           21699 non-null  int64  
 7   ab          21699 non-null  int64  
 8   r           21699 non-null  int64  
 9   h           21699 non-null  int64  
 10  X2b         21699 non-null  int64  
 11  X3b         21699 non-null  int64  
 12  hr          21699 non-null  int64  
 13  rbi         21687 non-null  float64
 14  sb          21449 non-null  float64
 15  cs          17174 non-null  float64
 16  bb          21699 non-null  int64  
 17  so          20394 non-null  float64
 18  ibb         14171 non-null  float64
 19  hbp         21322 non-null  float64
 20  sh          20739 non-null  float64
 21  sf          14309 non-null  float64
 22  gidp        16427 non-null  float64
dtypes: float64(9), int64(11), object(3)
memory usage: 3.8+ MB

但是,使用to_string将以表格形式返回DataFrame的字符串表示形式,尽管它并不总是适合控制台宽度:

print(baseball.iloc[-20:,:12].to_string())
       Unnamed: 0         id  year  stint team  lg    g   ab   r    h  X2b  X3b
21679       89474  finlest01  2007      1  COL  NL   43   94   9   17    3    0
21680       89480  embreal01  2007      1  OAK  AL    4    0   0    0    0    0
21681       89481  edmonji01  2007      1  SLN  NL  117  365  39   92   15    2
21682       89482  easleda01  2007      1  NYN  NL   76  193  24   54    6    0
21683       89489  delgaca01  2007      1  NYN  NL  139  538  71  139   30    0
21684       89493  cormirh01  2007      1  CIN  NL    6    0   0    0    0    0
21685       89494  coninje01  2007      2  NYN  NL   21   41   2    8    2    0
21686       89495  coninje01  2007      1  CIN  NL   80  215  23   57   11    1
21687       89497  clemero02  2007      1  NYA  AL    2    2   0    1    0    0
21688       89498  claytro01  2007      2  BOS  AL    8    6   1    0    0    0
21689       89499  claytro01  2007      1  TOR  AL   69  189  23   48   14    0
21690       89501  cirilje01  2007      2  ARI  NL   28   40   6    8    4    0
21691       89502  cirilje01  2007      1  MIN  AL   50  153  18   40    9    2
21692       89521  bondsba01  2007      1  SFN  NL  126  340  75   94   14    0
21693       89523  biggicr01  2007      1  HOU  NL  141  517  68  130   31    3
21694       89525  benitar01  2007      2  FLO  NL   34    0   0    0    0    0
21695       89526  benitar01  2007      1  SFN  NL   19    0   0    0    0    0
21696       89530  ausmubr01  2007      1  HOU  NL  117  349  38   82   16    3
21697       89533   aloumo01  2007      1  NYN  NL   87  328  51  112   19    1
21698       89534  alomasa02  2007      1  NYN  NL    8   22   1    3    1    0

默认情况下,将跨多行打印ames:

pd.DataFrame(np.random.randn(3, 12))
0 1 2 3 4 5 6 7 8 9 10 11
0 0.417027 -0.662031 0.217932 0.180797 1.995120 1.281095 -2.085882 0.416237 -1.994071 -0.890021 0.143770 1.171460
1 -1.453006 -0.495643 0.861393 0.297495 -1.656289 1.218641 -1.247598 2.480623 -2.064665 -0.365235 0.302656 1.092608
2 -2.301177 -0.419567 1.743266 -0.342251 -0.157273 0.086404 1.237279 0.540404 0.076418 -0.256506 -0.010054 -1.135659

您可以通过设置display.width选项来更改单行打印量:

pd.set_option("display.width", 20)  # default is 80
pd.DataFrame(np.random.randn(3, 10))
0 1 2 3 4 5 6 7 8 9
0 -0.108353 -1.836611 0.394449 -0.730400 0.014042 1.942234 0.892721 1.552146 -1.055182 1.718318
1 -0.194978 -1.374333 0.333061 0.606212 -0.536571 -0.755143 -0.222781 0.717554 0.062236 0.746278
2 -0.912129 -1.722085 -0.756400 0.456704 -0.782453 -0.630722 -0.846685 2.628396 -0.960793 0.873283

您可以通过设置display.max_colwidth来调整各个列的最大宽度。

datafile = {
    "filename": ["filename_01", "filename_02"],
    "path": [
        "media/user_name/storage/folder_01/filename_01",
        "media/user_name/storage/folder_02/filename_02",
    ],
}

pd.set_option("display.max_colwidth", 30)

pd.DataFrame(datafile)
Out[129]: 
      filename                           path
0  filename_01  media/user_name/storage/fo...
1  filename_02  media/user_name/storage/fo...

pd.set_option("display.max_colwidth", 100)

pd.DataFrame(datafile)
Out[131]: 
      filename                                           path
0  filename_01  media/user_name/storage/folder_01/filename_01
1  filename_02  media/user_name/storage/folder_02/filename_02

您也可以通过expand_frame_repr选项禁用此功能。这将打印一个块中的表格。

DataFrame列属性访问和IPython完成

如果DataFrame列标签是有效的Python变量名,则可以像访问属性一样访问该列:

df = pd.DataFrame({"foo1": np.random.randn(5), "foo2": np.random.randn(5)})
df
foo1 foo2
0 0.918843 0.952254
1 -0.763186 -0.939310
2 -0.028110 0.084321
3 -1.428816 0.124293
4 -1.769076 0.544357

这些列还连接到IPython完成机制,因此它们可以用tab键完成:

df.foo1, df.foo2
(0    0.918843
 1   -0.763186
 2   -0.028110
 3   -1.428816
 4   -1.769076
 Name: foo1, dtype: float64,
 0    0.952254
 1   -0.939310
 2    0.084321
 3    0.124293
 4    0.544357
 Name: foo2, dtype: float64)


这篇关于【pandas官方文档-用户指南】2.数据结构简介的文章就介绍到这儿,希望我们推荐的文章对大家有所帮助,也希望大家多多支持为之网!


扫一扫关注最新编程教程