一、什么是索引对象
索引对象的理解其实很简单,索引对象的作用主要是负责管理轴标签和其他元数据的。构建Series和DataFrame时,所用到的任何数组或其他序列的标签都会被转换成一个Index。pandas中Index类来表示基本索引对象。来看两个打印,分别是索引对象所在类名输出,一个是其__doc__属性。
import pandas as pd
import numpy as np
print(pd.Index)
print(pd.Index.__doc__)
二、索引对象的获取
import pandas as pd
import numpy as np
a = pd.Index([1, 2, 3])
b = pd.Index(list('abc'))
print(a)
print(b)
"""
结果
Index([1, 2, 3], dtype='int64')
Index(['a', 'b', 'c'], dtype='object')
"""
我们来看一下上述输出的最后有两个例子,即使用pd.Index()方法就能创建一个索引对象。第一个输出dtype='int64',第二个dtype='object',第二个输出难道不是dtype='string',要回答这个问题,我们先看另外一个例子:
import pandas as pd
import numpy as np
data_test = pd.DataFrame({"Yes_No": [True, False],
"Value": [1.1, 2],
"Type": ['Small', 'large']
})
print(data_test.dtypes)
"""
结果
Yes_No bool
Value float64
Type object
dtype: object
"""
“Type”行数据的类型为object,并不是String,跟索引对象中的一致,这是为什么呢?简单的说就是:dtype对象来自NumPy,它描述ndarray中元素的类型。ndarray中的每个元素都必须具有相同的字节大小。对于int64和float64,它们是8个字节。但是对于字符串,字符串的长度不是固定的,Pandas使用了一个对象ndarray来保存指向对象的指针,而不是直接在ndarray中保存字符串的字节,因此这种ndarray的dtype是object。
弄清楚这个问题,我们就可以看一下索引对象怎么获取了:
import pandas as pd
import numpy as np
df = pd.DataFrame({'time': ['2023-09-21', '2023-09-22', '2023-09-23'],
'count': [1, 2, 3]}, index=['a', 'b', 'c'])
print(df)
print('获取的索引对象为:', df.index)
print('获取的索引对象值为:', df.index.values)
"""
结果
time count
a 2023-09-21 1
b 2023-09-22 2
c 2023-09-23 3
获取的索引对象为: Index(['a', 'b', 'c'], dtype='object')
获取的索引对象值为: ['a' 'b' 'c']
"""
使用df.index获取索引对象,使用df.index.values获取索引对象数据。
三、索引的可重复性
索引对象的索引是可以重复的,这句话是什么意思呢?我们在构建DataFrame的时候传入的index是可以重复的,可以这样: index=['a','b','c'],可以这样index=['a','b','a'],还可以这样index=['a','a',None]等等。
import pandas as pd
import numpy as np
df = pd.DataFrame({'time': ['2023-09-21', '2023-09-22', '2023-09-23', '2023-09-24'],
'count': [1, 2, 3, 4]}, index=['a', 'b', 'a', 'b'])
print(df)
print(df.index.is_unique)
print(df.index.isna())
"""
结果
time count
a 2023-09-21 1
b 2023-09-22 2
a 2023-09-23 3
b 2023-09-24 4
False
[False False False False]
"""
第一行输出包含重复索引的DataFrame。
第二行代码使用is_unique()方法来判断索引是否是唯一不重复的,返回bool值。
第三行代码使用isna()方法来判断索引是否是None值。
四、索引的不可修改性
索引的不可修改性就是说这个索引是不支持进行修改的,但是可以进行重置。换句话说索引是不支持部分修改的,可以全部替换。
import pandas as pd
import numpy as np
df = pd.DataFrame({'time': ['2023-09-21', '2023-09-22', '2023-09-23', '2023-09-24'],
'count': [1, 2, 3, 4]}, index=['a', 'b', 'a', 'b'])
print(df.index[0])
df.index[0] = "p"
"""
结果
报错:
TypeError: Index does not support mutable operations
"""
那么该如何进行这个索引的修改的呢?介绍重置索引的方法:
1. 直接赋值替换
import pandas as pd
import numpy as np
df = pd.DataFrame({'time': ['2023-09-21', '2023-09-22', '2023-09-23', '2023-09-24'],
'count': [1, 2, 3, 4]}, index=['a', 'b', 'a', 'b'])
df.index = ['e', 'r', 't', 'y']
print(df)
"""
#结果
time count
e 2023-09-21 1
r 2023-09-22 2
t 2023-09-23 3
y 2023-09-24 4
#替换索引成功
"""
2.使用set_index(),reset_index()和reindex()方法
在pandas中常用的有几个方法如set_index() 和 reset_index() 以及 reindex() ,这几个方法看着很相近但是如果没有完全搞明白区分它们的不同的话,在日后的使用中会极大影响数据预处理时的工作效率。为了更好的以不同例子说明这几个方法的作用与区别,如下先声明一个初始数据集。
import pandas as pd
import numpy as np
# 生成模拟数据
generd = ['男', '女']
boolean = [True, False]
df = pd.DataFrame({"height": np.random.randint(150, 190, 5),
"weight": np.random.randint(40, 80, 5),
"age": np.random.randint(20, 100, 5),
"gender": [generd[x] for x in np.random.randint(0, len(generd), 5)],
"smoker": [boolean[x] for x in np.random.randint(0, 2, 5)]
},
index=list("abcde"))
print(df)
"""
#结果
height weight age gender smoker
a 172 61 65 女 True
b 187 77 57 女 True
c 177 48 52 男 True
d 167 57 39 女 True
e 162 73 65 女 True
"""
(1)set_index()
DataFrame.set_index(keys, drop=True, append=False, inplace=False, verify_integrity=False)
set_index() 主要可以将数据表中指定的某列设置为索引或复合索引,如下是常涉及使用的几个参数:
keys:列标签或列标签/数组列表,需要设置为索引的列。
drop:默认为True,删除用作新索引的列,也就是当把某列设置为索引后,原来的列会移除。
append:是否将列附加到现有索引,默认为False。
inplace:输入布尔值,表示当前操作是否对原数据生效,默认为False。
如下代码说明,当keys参数设置为height字段时,height字段将变成索引列。同时因为drop=True 代表同时删除原数据中的height列,默认情况本身为True。
import pandas as pd
import numpy as np
# 生成模拟数据
generd = ['男', '女']
boolean = [True, False]
df = pd.DataFrame({"height": np.random.randint(150, 190, 5),
"weight": np.random.randint(40, 80, 5),
"age": np.random.randint(20, 100, 5),
"gender": [generd[x] for x in np.random.randint(0, len(generd), 5)],
"smoker": [boolean[x] for x in np.random.randint(0, 2, 5)]
},
index=list("abcde"))
df01 = df.set_index(keys="height",drop=True)
print(df01)
"""
#结果
weight age gender smoker
height
176 75 34 男 False
182 54 62 女 False
154 75 79 男 False
161 79 28 男 True
150 62 33 女 True
"""
当drop=False时,保留了原数据中的height列:
import pandas as pd
import numpy as np
# 生成模拟数据
generd = ['男', '女']
boolean = [True, False]
df = pd.DataFrame({"height": np.random.randint(150, 190, 5),
"weight": np.random.randint(40, 80, 5),
"age": np.random.randint(20, 100, 5),
"gender": [generd[x] for x in np.random.randint(0, len(generd), 5)],
"smoker": [boolean[x] for x in np.random.randint(0, 2, 5)]
},
index=list("abcde"))
df01 = df.set_index(keys="height", drop=False)
print(df01)
"""
#结果
weight age gender smoker
height
176 75 34 男 False
182 54 62 女 False
154 75 79 男 False
161 79 28 男 True
150 62 33 女 True
"""
new_index = df01.index.rename("这是索引")
print(new_index)
df01.index = new_index
print(df01)
"""
#结果
Index([188, 150, 156, 151, 189], dtype='int32', name='这是索引')
height weight age gender smoker
这是索引
188 188 55 33 女 True
150 150 77 21 女 True
156 156 61 97 男 False
151 151 67 72 男 True
189 189 77 73 女 True
"""
如下代码与之前的代码基本相似,也是将height字段将变成索引列。同时drop=False,代表保留原数据中的该列。但有明显不同之处是设置了append=True,这就代表将height列是以添加的额外附加的形式添加到现有索引中,但并不会把原来最初的索引移除。
import pandas as pd
import numpy as np
# 生成模拟数据
generd = ['男', '女']
boolean = [True, False]
df = pd.DataFrame({"height": np.random.randint(150, 190, 5),
"weight": np.random.randint(40, 80, 5),
"age": np.random.randint(20, 100, 5),
"gender": [generd[x] for x in np.random.randint(0, len(generd), 5)],
"smoker": [boolean[x] for x in np.random.randint(0, 2, 5)]
},
index=list("abcde"))
print(df)
print("=====================&