Dataframe 对象

import pandas as pd
import numpy as np

DataFrame 是一种二维标记数据结构,具有可能不同类型的列。您可以将其视为电子表格或 SQL 表,或 Series 对象的字典。它通常是最常用的 pandas 对象。

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

创建 DataFrame 对象

Series 一样,DataFrame 接受许多不同类型的输入:

以 Series 或 dict 为值的 dict

data = {
    "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"]),
}

结果索引将是各种系列的索引的并集。如果有任何嵌套的 dict,这些将首先转换为 Series。如果未传递任何列,则这些列将是 dict 键的有序列表。

pd.DataFrame(data)

onetwo
a1.01.0
b2.02.0
c3.03.0
dNaN4.0
pd.DataFrame(data, index=['d', 'b', 'a'])

onetwo
dNaN4.0
b2.02.0
a1.01.0
pd.DataFrame(data, index=['d', 'b', 'a'], columns=['two', 'three'])

twothree
d4.0NaN
b2.0NaN
a1.0NaN

以 list 或 ndarray 为值的 dict

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

data = {
    'one': [1.0, 2.0, 3.0, 4.0],
    'two': [4.0, 3.0, 2.0, 1.0],
}
pd.DataFrame(data)

onetwo
01.04.0
12.03.0
23.02.0
34.01.0
pd.DataFrame(data, index=['a', 'b', 'c', 'd'])

onetwo
a1.04.0
b2.03.0
c3.02.0
d4.01.0

结构化或记录数组

data = np.zeros((2,), dtype=[("A", "i4"), ("B", "f4"), ("C", "a10")])
data
array([(0, 0., b''), (0, 0., b'')],
      dtype=[('A', '<i4'), ('B', '<f4'), ('C', 'S10')])
data[:] = [
    (1, 2.0, 'Hello'),
    (2, 3.0, 'World'),
]
data
array([(1, 2., b'Hello'), (2, 3., b'World')],
      dtype=[('A', '<i4'), ('B', '<f4'), ('C', 'S10')])
pd.DataFrame(data)

ABC
012.0b'Hello'
123.0b'World'
pd.DataFrame(data, index=['first', 'second'])

ABC
first12.0b'Hello'
second23.0b'World'
pd.DataFrame(data, columns=['C', 'A', 'B'])

CAB
0b'Hello'12.0
1b'World'23.0

由 dict 组成的 list

data = [
    {'a': 1, 'b': 2},
    {'a': 5, 'b': 10, 'c': 20},
]
pd.DataFrame(data)

abc
012NaN
151020.0
pd.DataFrame(data, index=['first', 'second'])

abc
first12NaN
second51020.0
pd.DataFrame(data, columns=['a', 'b'])

ab
012
1510

以 tuple 为键的 dict

这样创建出的 DataFrame 具有多重索引框架。

df = pd.DataFrame(
    {
        ('a', 'b'): {('A', 'B'): 1, ('A', 'C'): 2},
        ('a', 'a'): {('A', 'C'): 3, ('A', 'B'): 4},
        ('a', 'c'): {('A', 'B'): 5, ('A', 'C'): 6},
        ('b', 'a'): {('A', 'C'): 7, ('A', 'B'): 8},
        ('b', 'b'): {('A', 'D'): 9, ('A', 'B'): 10},
    }
)
df

ab
bacab
AB1.04.05.08.010.0
C2.03.06.07.0NaN
DNaNNaNNaNNaN9.0

索引 'a''b' 返回的还是 DataFrame 对象,它是嵌套在 df2 里面的。

df['a']

bac
AB1.04.05.0
C2.03.06.0
DNaNNaNNaN
df['b']

ab
AB8.010.0
C7.0NaN
DNaN9.0

namedtuple 序列

namedtuple 的字段名称决定了 DataFrame 的列。剩下的命名元组(或元组)被简单地解包,它们的值被输入到 DataFrame 的行中。

from collections import namedtuple
Point = namedtuple('Point', 'x y')
pd.DataFrame([Point(0, 0), Point(0, 3), Point(2, 3)])

xy
000
103
223

如果这些元组中的任何一个比第一个 namedtuple 短,则相应行中后面的列被标记为缺失值。如果有任何比第一个命名元组长,则会引发 ValueError。

Point3D = namedtuple('Point3D', 'x y z')
pd.DataFrame([Point3D(0, 0, 0), Point3D(0, 3, 5), Point(2, 3)])

xyz
0000.0
1035.0
223NaN

dataclass 序列

from dataclasses import make_dataclass
Point = make_dataclass('Point', [('x', int), ('y', int)])
pd.DataFrame([Point(0, 0), Point(0, 3), Point(2, 3)])

xy
000
103
223

备用构造函数

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

AB
014
125
236

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

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

AB
014
125
236
data = np.zeros((2,), dtype=[("A", "i4"), ("B", "f4"), ("C", "a10")])
data
array([(0, 0., b''), (0, 0., b'')],
      dtype=[('A', '<i4'), ('B', '<f4'), ('C', 'S10')])
pd.DataFrame.from_records(data, index='C')

AB
C
b''00.0
b''00.0

DataFrame 对象的属性

data = {
    "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(data)
df

onetwo
a1.01.0
b2.02.0
c3.03.0
dNaN4.0
df.index
Index(['a', 'b', 'c', 'd'], dtype='object')
df.columns
Index(['one', 'two'], dtype='object')

类似 NumPy ndarray,可以对 DataFrame 对象进行转置:

df.T

abcd
one1.02.03.0NaN
two1.02.03.04.0

注意:DataFrame 并非完全像二维 NumPy ndarray 那样工作。

DataFrame 列操作

data = {
    "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(data)
df

onetwo
a1.01.0
b2.02.0
c3.03.0
dNaN4.0

可以在语义上认为 DataFrame 对象是索引 Series 对象的字典。因此,对 DataFrame 对象进行列操作和对 dict 对象进行增删改查等操作类似。

选择

df['one']
a    1.0
b    2.0
c    3.0
d    NaN
Name: one, dtype: float64

运算

df['three'] = df['one'] * df['two']
df

onetwothree
a1.01.01.0
b2.02.04.0
c3.03.09.0
dNaN4.0NaN
df['flag'] = df['one'] > 2
df

onetwothreeflag
a1.01.01.0False
b2.02.04.0False
c3.03.09.0True
dNaN4.0NaNFalse

删除

del df['two']
df

onethreeflag
a1.01.0False
b2.04.0False
c3.09.0True
dNaNNaNFalse
three = df.pop('three')
three
a    1.0
b    4.0
c    9.0
d    NaN
Name: three, dtype: float64
df

oneflag
a1.0False
b2.0False
c3.0True
dNaNFalse

插入

df['foo'] = 'bar'
df

oneflagfoo
a1.0Falsebar
b2.0Falsebar
c3.0Truebar
dNaNFalsebar

当插入一个与 DataFrame 没有相同索引的 Series 时,它将符合 DataFrame 的索引:

df["one_trunc"] = df["one"][:2]
df

oneflagfooone_trunc
a1.0Falsebar1.0
b2.0Falsebar2.0
c3.0TruebarNaN
dNaNFalsebarNaN

默认情况下,列在最后插入。插入函数可用于在列中的特定位置插入:

df.insert(1, "bar", df["one"])
df

onebarflagfooone_trunc
a1.01.0Falsebar1.0
b2.02.0Falsebar2.0
c3.03.0TruebarNaN
dNaNNaNFalsebarNaN
Previous
Next