Pandas 是一个专门用于数据处理和分析的 Python 库,它提供了众多强大的数据结构和函数,帮助用户更加轻松、高效地完成数据处理和分析任务。其中,DataFrame 数据类型是 Pandas 中非常重要的一种数据结构,可以方便地对二维表格数据进行操作、处理、统计和可视化等工作。
Pandas 中 DataFrame 的一些特点和优势,比如:
- 可以灵活处理不同类型的数据,包括数字、文本、日期等等。
- 提供了许多强大的数据处理函数,比如过滤、排序、聚合等操作。
- 方便进行数据可视化和统计分析,例如可视化不同变量之间的关系、计算各种统计量等。
- 易于与其他 Python 库相集成使用,比如 NumPy、Matplotlib 等库。
DataFrame([data, index, columns, dtype, copy]) #二维、大小可变、可能异构的表格数据。
class pandas.DataFrame(data=None, index=None, columns=None, dtype=None, copy=None)[source]
pandas.DataFrame() 是用于创建 DataFrame 数据类型的类,其参数如下:
- data:要传入 DataFrame 中的数据,可以是多种形式,包括 Numpy 数组、dicts、series、DataFrame 等。
- index:DataFrame 的索引。行标签可以是数字或字符串。如果没有显示指定索引,则会默认生成整数 RangeIndex(0, 1, 2, …, n)索引。
- columns:DataFrame 的列标签。必须提供列名。
- dtype:指定 DataFrame 中元素的类型,可以是 Numpy 类型或 Python 内置类型,比如 float、int、str 等。只允许一个数据类型。
- copy:如果复制输入数据,可以选择 True 或 False。
使用示例:
import pandas as pd
# 定义输入数据
data = {'name': ['Tom', 'Jerry', 'Mike', 'Jack'],
'age': [24, 25, 22, 26],
'city': ['Beijing', 'Shanghai', 'Guangzhou', 'Shenzhen']}
# 定义索引
index = ['a', 'b', 'c', 'd']
# 定义列标签
columns = ['name', 'age', 'city', 'salary']
# 定义元素类型
dtype = str
# 创建 DataFrame 对象
df = pd.DataFrame(data=data, index=index, columns=columns, dtype=dtype)
# 打印 DataFrame
print(df)
输出结果:
name age city salary
a Tom 24 Beijing NaN
b Jerry 25 Shanghai NaN
c Mike 22 Guangzhou NaN
d Jack 26 Shenzhen NaN
在上面的代码中,我们首先定义了一个字典 data,其中包括了我们要传入到 DataFrame 中的数据。接着,我们定义了一个列表 index,用于指定自定义索引。然后,我们定义了一个列表 columns,用于指定列标签,即每列的名称。最后,我们定义了一个字符串 dtype,指定每列的数据类型。
通过这些参数,我们调用 pandas.DataFrame() 方法,并将所有参数传入,创建了一个自定义索引和列标签的 DataFrame。最后,我们打印输出了 DataFrame。
DataFrame.index # DataFrame 的索引(行标签)。
DataFrame.columns # DataFrame 的列标签。
DataFrame.dtypes # 返回 DataFrame 中的数据类型。
DataFrame.info([verbose, buf, max_cols, ...]) # 打印 DataFrame 的简明摘要。
DataFrame.select_dtypes([include, exclude]) # 根据列数据类型返回 DataFrame 列的子集。
DataFrame.values # 返回 DataFrame 的 Numpy 表示。
DataFrame.axes # 返回表示 DataFrame 轴的列表。
DataFrame.ndim # 返回一个表示轴数/数组维数的 int。
DataFrame.size # 返回一个 int 表示此对象中的元素数。
DataFrame.shape # 返回表示 DataFrame 维度的元组。
DataFrame.memory_usage([index, deep]) # 以字节为单位返回每列的内存使用情况。
DataFrame.empty # 指示 Series/DataFrame 是否为空。
DataFrame.set_flags(*[, copy, ...]) # 返回具有更新标志的新对象。
DataFrame 的索引(行标签)。
使用示例:
import pandas as pd
# 创建一个 DataFrame
data = {'name': ['Alice', 'Bob', 'Charlie', 'David', 'Emily'],
'age': [25, 27, 23, 31, 22],
'gender': ['F', 'M', 'M', 'M', 'F']}
df = pd.DataFrame(data)
# 查看 DataFrame 的行索引
print("行索引:", df.index)
# 查看第一个行索引
print("第一个行索引:", df.index[0])
# 修改行索引
new_index = ['a', 'b', 'c', 'd', 'e']
df.index = new_index
print("修改后的行索引:", df.index)
输出结果:
行索引: RangeIndex(start=0, stop=5, step=1)
第一个行索引: 0
修改后的行索引: Index(['a', 'b', 'c', 'd', 'e'], dtype='object')
这里首先创建了一个包含姓名、年龄和性别信息的 DataFrame 对象,并使用 .index 获取了该 DataFrame 的行索引。然后使用索引 [0] 获取了第一个行索引,即 0。最后使用新的行索引列表将行索引进行了修改,并打印了新的行索引。
DataFrame 的列标签。
使用示例:
import pandas as pd
# 创建一个 DataFrame
data = {'name': ['Alice', 'Bob', 'Charlie', 'David', 'Emily'],
'age': [25, 27, 23, 31, 22],
'gender': ['F', 'M', 'M', 'M', 'F']}
df = pd.DataFrame(data)
# 查看 DataFrame 的列名
print("列名:", df.columns)
# 查看第一个列名
print("第一个列名:", df.columns[0])
# 修改列名
new_columns = ['Name', 'Age', 'Gender']
df.columns = new_columns
print("修改后的列名:", df.columns)
输出结果:
列名: Index(['name', 'age', 'gender'], dtype='object')
第一个列名: name
修改后的列名: Index(['Name', 'Age', 'Gender'], dtype='object')
这里首先创建了一个包含姓名、年龄和性别信息的 DataFrame 对象,并使用 .columns 获取了该 DataFrame 的列名。然后使用索引 [0] 获取了第一个列名,即 name。最后使用新的列名列表将列名进行了修改,并打印了新的列名。
返回 DataFrame 中的数据类型。
使用示例:
import pandas as pd
# 创建一个 DataFrame
data = {'name': ['Alice', 'Bob', 'Charlie', 'David', 'Emily'],
'age': [25, 27, 23, 31, 22],
'gender': ['F', 'M', 'M', 'M', 'F']}
df = pd.DataFrame(data)
# 查看 DataFrame 的数据类型
print("数据类型:\n", df.dtypes)
输出结果:
数据类型:
name object
age int64
gender object
dtype: object
这里首先创建了一个包含姓名、年龄和性别信息的 DataFrame 对象,并使用 .dtypes 获取了该 DataFrame 的各列数据类型。可以看到,‘name’ 和 ‘gender’ 列的数据类型为 object,而 ‘age’ 列的数据类型为 int64。
DataFrame.info(verbose=None, buf=None, max_cols=None, memory_usage=None, show_counts=None)[source]
DataFrame.info() 方法用于打印 DataFrame 的基本信息(包括索引类型、列数、数据类型、内存占用等)。
该方法的参数含义如下:
- verbose:控制输出的详细程度,为 True 时输出更详细的信息,为 False 时只输出基本信息;
- buf:控制输出到何处,默认为 None,表示输出到标准输出流;
- max_cols:设置输出时最多显示的列数,默认为 None,表示显示所有列;
- memory_usage:控制是否显示内存占用情况,默认为 None,表示自动判断是否显示内存占用;
- show_counts:控制每列非空值的数量是否显示,默认为 None,表示根据 DataFrame 大小自动判断是否显示每列的非空值数量。
该方法返回 None。
使用示例:
import pandas as pd
# 创建一个 DataFrame
data = {'name': ['Alice', 'Bob', 'Charlie', 'David', 'Emily'],
'age': [25, 27, 23, 31, 22],
'gender': ['F', 'M', 'M', 'M', 'F']}
df = pd.DataFrame(data)
# 查看 DataFrame 的基本信息
df.info()
输出结果:
<class 'pandas.core.frame.DataFrame'>
RangeIndex: 5 entries, 0 to 4
Data columns (total 3 columns):
# Column Non-Null Count Dtype
--- ------ -------------- -----
0 name 5 non-null object
1 age 5 non-null int64
2 gender 5 non-null object
dtypes: int64(1), object(2)
memory usage: 248.0+ bytes
该输出结果显示了该 DataFrame 的基本信息,包括索引类型、列数、数据类型、非空值数量和内存占用。
DataFrame.select_dtypes(include=None, exclude=None)
根据列数据类型返回 DataFrame 列的子集。
该方法的参数 include 和 exclude 控制筛选的方式,具体含义如下:
- include:包含的数据类型或数据类型的列表,如果指定则选择指定的数据类型,否则选择所有数据类型;
- exclude:排除的数据类型或数据类型的列表,如果指定则不选择指定的数据类型,否则选择所有数据类型。
其中 include 和 exclude 可以同时指定。
使用示例:
import pandas as pd
# 创建一个 DataFrame
data = {'name': ['Alice', 'Bob', 'Charlie', 'David', 'Emily'],
'age': [25, 27, 23, 31, 22],
'gender': ['F', 'M', 'M', 'M', 'F']}
df = pd.DataFrame(data)
# 选择 string 类型的列
df_str = df.select_dtypes(include='object')
print(df_str)
# 排除 int 类型的列
df_ex = df.select_dtypes(exclude='int64')
print(df_ex)
输出结果:
name gender
0 Alice F
1 Bob M
2 Charlie M
3 David M
4 Emily F
name gender
0 Alice F
1 Bob M
2 Charlie M
3 David M
4 Emily F
该示例代码中首先创建了一个包含姓名、年龄和性别信息的 DataFrame 对象,然后分别根据数据类型选择或排除列,并打印了筛选后的结果。可以看到,df_str 只包含 string 类型的列(即 ‘name’ 和 ‘gender’),而 df_ex 不包含 int64 类型的列(即 ‘age’)。
返回一个 NumPy 数组对象,数组的形状为 (行数, 列数),数据类型为 object。
通常情况下,我们不需要直接访问该属性,而是使用 Pandas 提供的各种方法对 DataFrame 进行操作。但是在一些特殊情况下(例如需要使用第三方库或需要进行较为底层的操作),直接访问 DataFrame.values 很有用。
需要注意的是,DataFrame.values 返回的是一个视图(view),而不是副本(copy)。这意味着如果修改返回的 NumPy 数组,则会修改原始的 DataFrame 数据。因此,我们应该尽量避免修改 DataFrame.values 的结果。
使用示例:
import pandas as pd
# 创建一个 DataFrame
data = {'name': ['Alice', 'Bob', 'Charlie', 'David', 'Emily'],
'age': [25, 27, 23, 31, 22],
'gender': ['F', 'M', 'M', 'M', 'F']}
df = pd.DataFrame(data)
# 访问 DataFrame.values 属性
values = df.values
print(values)
输出结果:
[['Alice' 25 'F']
['Bob' 27 'M']
['Charlie' 23 'M']
['David' 31 'M']
['Emily' 22 'F']]
该示例代码中首先创建了一个包含姓名、年龄和性别信息的 DataFrame 对象,然后访问 DataFrame.values 属性,并打印了返回的 NumPy 数组的值。
DataFrame.axes 是 pandas 中 DataFrame 对象的一个属性。它返回一个元组,其中包含两个对象,即行轴(row axis)标签和列轴(column axis)标签。这两个对象都是 Index 类型的数组,用于表示 DataFrame 中的行和列的标签。
具体来说,DataFrame.axes 返回的元组中第一个元素是行轴标签数组,它是一个长度为行数的 Index 对象,包含了 DataFrame 中所有行的标签。第二个元素是列轴标签数组,它是一个长度为列数的 Index 对象,包含了 DataFrame 中所有列的标签。
需要注意的是,Index 对象是 pandas 的一种数据结构,类似于 Python 中的列表,但具有更多的方法和属性,例如可以使用 .tolist() 方法将其转换为 Python 列表,或使用 .rename() 方法重命名其中的元素。
使用示例:
import pandas as pd
# 创建一个 DataFrame
data = {'name': ['Alice', 'Bob', 'Charlie', 'David', 'Emily'],
'age': [25, 27, 23, 31, 22],
'gender': ['F', 'M', 'M', 'M', 'F']}
df = pd.DataFrame(data)
# 访问 DataFrame.axes 属性
axes = df.axes
print(axes)
print("行轴标签:", axes[0].tolist())
print("列轴标签:", axes[1].tolist())
输出结果:
[RangeIndex(start=0, stop=5, step=1), Index(['name', 'age', 'gender'], dtype='object')]
行轴标签: [0, 1, 2, 3, 4]
列轴标签: ['name', 'age', 'gender']
在这个示例代码中,首先创建了一个包含姓名、年龄和性别信息的 DataFrame 对象,然后访问了 DataFrame.axes 属性,并打印了返回的轴标签数组。可以看到,该属性返回的是一个长度为 2 的元组(tuple)对象,其中第一个元素是行轴标签,第二个元素是列轴标签,两个元素的类型都是 Index 对象,它们的元素数分别等于 DataFrame 对象的行数和列数。我们可以使用 .tolist() 方法将它们转换为 Python 列表对象进行操作。
另外需要注意,DataFrame.axes 属性不同于 DataFrame.index 和 DataFrame.columns 属性,它返回的是所有轴标签,而不是行标签和列标签。
返回 DataFrame 的维度数目。也就是说,它返回的是 DataFrame 中轴的数量。如果是Series, 返回 1。如果是 DataFrame, 返回 2 。
使用示例:
import pandas as pd
# 创建一个二维 DataFrame
data = {'name': ['Alice', 'Bob', 'Charlie', 'David', 'Emily'],
'age': [25, 27, 23, 31, 22],
'gender': ['F', 'M', 'M', 'M', 'F']}
df = pd.DataFrame(data)
# 访问 DataFrame.ndim 属性
print(df.ndim)
输出结果:
2
在这个示例中,首先创建了一个包含姓名、年龄和性别信息的 DataFrame 对象,然后访问了 DataFrame.ndim 属性,并打印了返回的值。由于该 DataFrame 对象为二维数组,因此其维度数目为 2,属性返回值为 2。
需要注意的是,DataFrame.ndim 属性的返回值只与 DataFrame 对象内部的数据结构有关,而与其中的数据值无关。因此,即使 DataFrame 中包含空值或不一致的数据类型等情况,DataFrame.ndim 的值也不会受到影响。
返回的是一个整数值,表示 DataFrame 包含的元素数量。在二维的 DataFrame 对象中,包含的元素数量等于其行数与列数之积。
使用示例:
import pandas as pd
# 创建一个二维 DataFrame
data = {'name': ['Alice', 'Bob', 'Charlie', 'David', 'Emily'],
'age': [25, 27, 23, 31, 22],
'gender': ['F', 'M', 'M', 'M', 'F']}
df = pd.DataFrame(data)
# 访问 DataFrame.size 属性
print(df.size)
输出结果:
15
在这个示例中,首先创建了一个包含姓名、年龄和性别信息的 DataFrame 对象,然后访问了 DataFrame.size 属性,并打印了返回的值。由于该 DataFrame 对象中包含了 5 行和 3 列的数据,因此其大小为 15,属性返回值为 15。
需要注意的是,DataFrame.size 属性返回的是整个 DataFrame 对象内部的元素数量,不管它们是空值或有效的数据值。因此,即使 DataFrame 中包含空值或不一致的数据类型等情况,DataFrame.size 的值也会受到所有元素数量的影响。
返回的是一个元组,包含两个整数值,分别表示 DataFrame 的行数和列数。例如,对于一个包含 5 行、3 列数据的 DataFrame 对象,DataFrame.shape 的返回值将会是 (5, 3)。
使用示例:
import pandas as pd
# 创建一个 DataFrame
data = {'name': ['Alice', 'Bob', 'Charlie', 'David', 'Emily'],
'age': [25, 27, 23, 31, 22],
'gender': ['F', 'M', 'M', 'M', 'F']}
df = pd.DataFrame(data)
# 访问 DataFrame.shape 属性
print(df.shape)
输出结果:
(5, 3)
在这个示例中,首先创建了一个包含姓名、年龄和性别信息的 DataFrame 对象,然后访问了 DataFrame.shape 属性,并打印了返回的值。由于该 DataFrame 对象中包含了 5 行和 3 列的数据,因此其形状为 (5, 3),属性返回值为 (5, 3) 的元组。
需要注意的是,DataFrame.shape 的返回值只与 DataFrame 对象内部的数据结构有关,而与其中的数据值无关。因此,即使 DataFrame 中包含空值或不一致的数据类型等情况,DataFrame.shape 的值也不会受到影响。
DataFrame.memory_usage(index=True, deep=False)
以字节为单位返回每列的内存使用情况。
DataFrame.memory_usage(index=True, deep=False) 方法接受两个参数:
- index: 一个布尔值,指示是否计算索引占用的内存大小。默认为 True。
- deep: 一个布尔值,指示是否考虑每个元素的实际大小(而非指针)。如果设置为 True,则计算每个元素的实际空间大小;否则,只计算指针的大小。默认为 False。
其中,index 参数为可选参数,用于指示是否计算索引所占用的内存。如果该参数为 True,则会额外计算 DataFrame 的索引所占用的内存大小;否则不计算。默认情况下,该参数为 True。
deep 参数也是可选参数,用于指示是否考虑每个元素的实际大小(而非指针)。如果该参数为 True,则会计算每个元素的实际空间大小,包括各种数据类型的元素,例如字符串、浮点数以及布尔值等等。如果该参数为 False,则仅计算指针的大小。默认情况下,该参数为 False。
需要注意的是,对于不同的数据类型而言,它们占用的内存大小是不同的。例如,整数、浮点数、字符串等不同类型的数据,在占用内存大小方面有着明显的差异。因此,在使用 DataFrame.memory_usage() 方法时,需要特别注意数据类型的影响。此外,当数据量比较大或者需要精确计算内存占用时,可以使用 deep=True 参数来更加准确地计算每个元素的实际空间大小。
使用示例:
import pandas as pd
# 创建一个 DataFrame
data = {'name': ['Alice', 'Bob', 'Charlie', 'David', 'Emily'],
'age': [25, 27, 23, 31, 22],
'gender': ['F', 'M', 'M', 'M', 'F']}
df = pd.DataFrame(data)
# 计算每列占用内存的大小
mem_usage = df.memory_usage(index=True, deep=False)
print(mem_usage)
输出结果:
Index 128
name 40
age 40
gender 40
dtype: int64
在这个示例中,首先创建了一个包含姓名、年龄和性别信息的 DataFrame 对象,然后通过调用 DataFrame.memory_usage() 方法来计算每列占用内存的大小。由于该 DataFrame 对象中包含 5 行和 3 列的数据,因此返回了一个包含 4 个元素的 Series,分别表示索引、姓名、年龄和性别这 4 列所占用的内存大小。
需要注意的是,DataFrame.memory_usage() 方法默认忽略了一些不占用实际空间的元素,例如索引和空值。如果想计算每个元素的实际空间大小,需要指定 deep=True 参数。同时,由于元素的存储方式可能因数据类型而异,因此使用 deep=True 将会更加准确,但也会更加耗时。
DataFrame.empty 是一个布尔值,用于判断一个 DataFrame 是否为空。如果 DataFrame 为空,则返回 True;否则返回 False。
具体来说,当 DataFrame 对象不包含任何数据时,即行数和列数都为 0 时,DataFrame.empty 返回 True;否则返回 False。在实际应用中,可以使用该属性来检查一个 DataFrame 是否为空,从而避免在处理空数据时出现异常。
使用示例:
import pandas as pd
# 创建一个空的 DataFrame
df1 = pd.DataFrame()
# 创建一个非空 DataFrame
df2 = pd.DataFrame({'col1': [1, 2, 3], 'col2': ['a', 'b', 'c']})
# 检查是否为空
print(df1.empty)
print(df2.empty)
输出结果:
True
False
在这个示例中,首先创建了两个 DataFrame 对象,一个为空,另一个包含两列数据。然后分别调用了它们的 empty 属性来检查是否为空。由于第一个 DataFrame 为空,因此返回值为 True;而第二个 DataFrame 不为空,因此返回值为 False。
需要注意的是,DataFrame.empty 返回的是一个布尔值,因此可以直接将其作为条件进行判断。
例如,可以使用以下代码来检查某个 DataFrame 是否为空:
if df.empty:
print('DataFrame is empty')
else:
print('DataFrame is not empty')
在这个示例中,使用了 if 语句来检查 df 是否为空。如果 df 为空,则打印“DataFrame is empty”;否则打印“DataFrame is not empty”。
DataFrame.set_flags(*, copy=False, allows_duplicate_labels=None)
用于设置 DataFrame 对象的一些标志位。它返回一个新的 DataFrame 对象,该对象与原对象的副本相同,但具有修改后的标志位。
该方法接受以下参数:
- copy:一个布尔值,指示是否将 DataFrame 复制到内存中。如果为 True,则将复制 DataFrame,否则不进行复制。默认为 False。
- allows_duplicate_labels:一个布尔值或字符串,指示是否允许 DataFrame 中含有相同的列名。如果为 True,则允许存在相同的列名;如果为 False,则不允许存在相同的列名;如果为字符串,则表示相同的列名必须属于该字符串中的某个集合。默认为 None,即根据 Pandas 版本自动判断是否允许存在相同的列名。
需要注意的是,DataFrame.set_flags() 方法能够设置的标志位可能会随着 Pandas 版本的更新而发生变化。因此,建议在使用该方法时查看相应的文档或源代码,以确保能够正确设置标志位。
使用示例:
import pandas as pd
# 创建一个 DataFrame 对象
df = pd.DataFrame({'A': [1, 2, 3], 'B': [4, 5, 6]})
# 设置标志位
df1 = df.set_flags(copy=True, allows_duplicate_labels=True)
# 打印新旧 DataFrame 对象的属性
print(f"df: {df._data}\n{df.columns}\n")
print(f"df1: {df1._data}\n{df1.columns}\n")
# 修改新 DataFrame 对象
df1['A'] = [4, 5, 6]
df1['C'] = [7, 8, 9]
# 打印修改后的新 DataFrame 对象
print(df1)
输出结果:
df: BlockManager
Items: Index(['A', 'B'], dtype='object')
Axis 1: RangeIndex(start=0, stop=3, step=1)
IntBlock: slice(0, 2, 1), 2 x 3, dtype: int64
Index(['A', 'B'], dtype='object')
df1: BlockManager
Items: Index(['A', 'B'], dtype='object')
Axis 1: RangeIndex(start=0, stop=3, step=1)
IntBlock: slice(0, 2, 1), 2 x 3, dtype: int64
Index(['A', 'B'], dtype='object')
A B C
0 4 4 7
1 5 5 8
2 6 6 9
在这个示例中,首先创建了一个 DataFrame 对象 df。然后调用 df.set_flags() 方法来设置标志位,将 copy 标志位设置为 True,并将 allows_duplicate_labels 标志位设置为 True。接着使用 df1._data 和 df1.columns 分别获取新 DataFrame 对象的数据和列名,并打印出来以便比较。可以看到,新 DataFrame 对象与原对象的数据和列名相同,但是它们具有不同的内存地址,即它们是不同的对象。最后,修改新 DataFrame 对象的数据和列名,并打印出来以确认修改结果。
需要注意的是,此处设置的 copy 标志位为 True,即会复制 DataFrame 对象。因此,在进行一些修改操作时,应该基于新 DataFrame 对象而不是原 DataFrame 对象。否则可能会产生意外的副作用。