DataFrame数据框是一个表格型的数据结构,设计初衷是将Series的使用场景从一维拓展到多维。DataFrame既有行索引,也有列索引。
- 行索引:index
- 列索引:columns
- 值:values(NumPy二维数组)
创建DataFrame
字典嵌套列表创建数据框:
import pandas as pd
d = {"Name": ["Alex", "Bob", "Clarke"], "Age": [10, 11, 12]}
df = pd.DataFrame(d, index=["a", "b", "c"]) # 添加行索引
print(df)
# 输出
# Name Age
# a Alex 10
# b Bob 11
# c Clarke 12
列表创建数据框:
data = [["Alex", 10], ["Bob", 11], ["Clarke", 12]] # 嵌套列表
df = pd.DataFrame(data, columns=["Name", "Age"]) # 添加列标签索引
print(df)
# 输出
# Name Age
# 0 Alex 10
# 1 Bob 11
# 2 Clarke 12
列表嵌套字典创建数据框:
data = [{"Name": "Alex", "Age": 12}, {"Name": "Bob", "Age": 16, "Sex": "0"}]
df = pd.DataFrame(data)
print(df)
# 输出
# Name Age Sex
# 0 Alex 12 NaN
# 1 Bob 16 0
基本属性和方法
d = {"Name": ["Alex", "Bob", "Clarke"], "Age": [10, 11, 12]}
df = pd.DataFrame(d, index=["a", "b", "c"])
print(df.shape) # 形状,查看维度,几行几列
print(df.columns) # 列索引
print(df.index) # 行索引
print(df.values) # 二维数组数据
print(df.dtypes) # 查看每列数据类型
print(df.Age.dtype) # 查看指定列数据类型
print(df.describe()) # 查看每列描述性统计量
print(df.info()) # 查看数据框基本信息,维度、列名称、数据格式、所占空间等
print(df.head(2)) # 查看前几条数据,默认5
print(df.tail(2)) # 查看后几条数据,默认5
索引
列索引
对列进行索引,通过类似字典的方式,或通过属性的方式。
可以将DataFrame的列获取为一个Series,返回的Series拥有原DataFrame相同的索引,且name属性也已经设置好了,就是相应的列名。
列索引选取数据列:
d = {"Name": ["Alex", "Bob"], "Age": [10, 11], "Sex": [0, 1]}
df = pd.DataFrame(d)
print(df["Age"]) ## 或 df.Age
# 输出
# 0 10
# 1 11
# Name: Age, dtype: int64
print(df[["Name", "Sex"]]) # 一次取多列得到的类型是:数据框
行索引
数据框默认先取列索引,不能直接取行索引,取行索引使用.loc[]加index,或使用.iloc[]加整数来取行索引。同样返回一个Series,index为原来的columns。
行索引选取数据行:
d = {"Name": ["Alex", "Bob", "Clarke"], "Age": [10, 11, 18], "Sex": [0, 1, 0]}
df = pd.DataFrame(d, index=["a", "b", "c"])
print(df.loc["a"])
# 输出
# Name Alex
# Age 10
# Sex 0
# Name: a, dtype: object
print(df.loc[["a", "c"]]) # 一次取多行得到的类型是:数据框
print(df.iloc[[0, 2]])
元素索引
print(df["Name"]["a"]) # 先取列,再取行
print(df.loc["a"]["Name"]) # 先取行,再取列
print(df.loc["a", "Name"]) # Alex
print(df.iloc[0, 0]) # Alex
层次化索引
创建多层行索引,隐式构造:
index = [
["1班", "1班", "1班", "2班", "2班", "2班"],
["张三", "李四", "王五", "赵六", "孙七", "周八"],
]
columns = [
["期中", "期中", "期中", "期末", "期末", "期末"],
["语文", "数学", "英语", "语文", "数学", "英语"],
]
data = [
[70, 80, 88, 85, 66, 97],
[90, 87, 78, 85, 95, 77],
[70, 80, 88, 75, 96, 95],
[75, 84, 80, 85, 76, 97],
[71, 80, 68, 85, 96, 87],
[70, 81, 88, 85, 96, 93],
]
df = pd.DataFrame(data, index=index, columns=columns)
print(df)
"""
期中 期末
语文 数学 英语 语文 数学 英语
1班 张三 70 80 88 85 66 97
李四 90 87 78 85 95 77
王五 70 80 88 75 96 95
2班 赵六 75 84 80 85 76 97
孙七 71 80 68 85 96 87
周八 70 81 88 85 96 93
"""
显示构造,pd.MultiIndex.from_arrays()使用数组,还可以使用元组from_tuples(),使用笛卡尔积from_product()。
索引堆叠
index = pd.MultiIndex.from_product([["1班", "2班"], ["张三", "李四", "王五"]])
columns = pd.MultiIndex.from_product([["期中", "期末"], ["语文", "数学", "英语"]])
data = [
[70, 80, 88, 85, 66, 97],
[90, 87, 78, 85, 95, 77],
[70, 80, 88, 75, 96, 95],
[75, 84, 80, 85, 76, 97],
[71, 80, 68, 85, 96, 87],
[70, 81, 88, 85, 96, 93],
]
df = pd.DataFrame(data, index=index, columns=columns)
df2 = df.stack() # 默认将最里层列索引变成行索引
df3 = df2.unstack() # 将行索引变成列索引
切片
直接用中括号时:索引优先对列进行操作,切片优先对行进行操作。
行切片:
d = {"Name": ["Alex", "Bob", "Clarke"], "Age": [10, 11, 18], "Sex": [0, 1, 0]}
df = pd.DataFrame(d, index=["a", "b", "c"])
print(df[0:2]) # 左闭右开
print(df["a":"c"]) # 左闭右闭
列切片,须先进行行切片:
print(df.loc[:, "Name":"Sex"])
print(df.iloc[:, 0:2])
总结:
- 取一行或一列:索引
- 取连续的多行或多列:切片
- 取不连续多行或多列:中括号
DataFrame运算
DataFrame之间的运算,会自动对齐索引进行运算。如果索引不对应,则补NaN,DataFrame没有广播机制。同样,可以使用add()函数来填充数据。
聚合函数
d = [[4, 1, 9], [2, 1, 8], [1, 3, 2]]
df = pd.DataFrame(d)
df.count() # 非空元素的数量
df.values.sum() # 所有数之和
df.sum() # 默认axis=0,对列求和
df.mean() # 平均值
df.max() # 最大值,最小值为 min()
df.median() # 中位数
df.std() # 标准差,方差为 var()
df.value_counts() # 统计元素出现次数
df.cumsum() # 累加
df.cov() # 协方差
df.corr() # 所有特征相关系数
df.corrwith(df[1]) # 单一特征相关系数