DataFrame相关操作
假设df为DataFrame类型的对象。
列操作
- 获取列【哪个更好些?】
- df[列索引]
- df.列索引
- 增加(修改)列:df[列索引] = 列数据
- 删除列
- del df[列索引]
- df.pop(列索引)
- df.drop(列索引或数组)
行操作
- 获取行
- df.loc 根据标签进行索引。
- df.iloc 根据位置进行索引。
- df.ix 混合索引。先根据标签索引,如果没有找到,则根据位置进行索引(前提是标签不是数值类型)。【已不建议使用】
- 增加行:append【多次使用append增加行会比连接计算量更大,可考虑使用pd.concat来代替。】
- 删除行
- df.drop(行索引或数组)
行列混合操作:
- 先获取行,再获取列。
- 先获取列,在获取行。
说明:
- drop方法既可以删除行,也可以删除列,通过axis指定轴方向。【可以原地修改,也可以返回修改之后的结果。】
- 通过df[索引]访问是对列进行操作。
- 通过df[切片]访问是对行进行操作。【先按标签,然后按索引访问。如果标签是数值类型,则仅会按标签进行匹配。】
- 通过布尔索引是对行进行操作。
- 通过数组索引是对列进行操作。
在对行或列进行操作时,如果针对多行(列)进行操作?如果是不连续的呢?
df = pd.DataFrame([[1, 2, 3], [4, 5, 6]], columns=["a", "b", "&"])
display(df)
# 获取列,有两种语法:
# 1 df["列索引"]
# 2 df.列索引
# display(df["a"])
# display(df.a)
# display(type(df["a"]))
# 建议大家使用第1种方式,因为第一种方式局限性较小,不要求列标签(列索引)必须是Python中合法的标示符。
# 第二种方式要求列标签必须是Python中合法的标识符。
# df["&"]
# df.&
# df[列索引]的方式,永远只支持标签索引,不支持位置索引,因此,不会出现混淆,可以放心的使用。
# df[0]
# 修改列
# df["a"] = [100, 400]
# 增加列
# df["new_column"] = [100, 200]
# 增加或修改列,我们通常都是基于现有列的数据进行计算得出,而不是会自行指定数据内容。
# df = pd.DataFrame([[1, 2, 3], [4, 5, 6]], columns=["a", "b", "age"])
# 过年,每个人的年龄增1。
# df["age"] = df["age"] + 1
# df
df = pd.DataFrame(np.random.randint(100, 200,size=(4, 3)), index=["第一季度", "第二季度", "第三季度", "第四季度"],
columns=["苹果", "香蕉", "葡萄"])
# df["合计"] = df["苹果"] + df["香蕉"] + df["葡萄"]
# df
# 删除列
# del df["苹果"]
# df
# 删除并返回列索引所对应的value。
# df.pop("苹果")
# df
# axis=1 删除列。 inplace:是否就地修改。
# df.drop("苹果", axis=1, inplace=True)
np.random.seed(0)
df = pd.DataFrame(np.random.randint(100, 200,size=(4, 3)), index=["第一季度", "第二季度", "第三季度", "第四季度"],
columns=["苹果", "香蕉", "葡萄"])
display(df)
# DataFrame行的操作。
# 获取行。
# 我们不能通过df["行标签"]的方式获取一行数据。因为这种语法只能获取一列。
# df["第一季度"]
# df.loc["标签索引"] df.iloc[位置索引] 获取行
# df.loc["第一季度"]
# df.iloc[2]
# df["苹果"]
# 增加行
# DataFrame的一行或者一列都是Series类型,Series的name属性就是作为DataFrame的行标签或者列标签。
# 如果Series没有显式设置name属性,则无法作为一行加入到DataFrame中,因为加入之后,该行没有行标签。
# row = pd.Series([100, 200, 300], name="新加入的行", index=["苹果", "香蕉", "葡萄"])
# df.append(row)
# 我们可以在append方法中,将ignore_index设置为True(默认为False),这样,加入的行(Series)中,name属性
# 就不是必须的了(可有可无)。
# ignore_index如果设置为True,则会丢弃以前的索引,而生成新的索引(从0开始,增量为1的索引)。
# row = pd.Series([100, 200, 300], index=["苹果", "香蕉", "葡萄"])
# df.append(row, ignore_index=True)
# append 方法既可以加入一行(参数为Series类型),也可以加入多行(参数为DataFrame类型)。
rows = pd.DataFrame([[12, 20, 50], [11, 90, 23]], columns=["苹果", "香蕉", "葡萄"], index=["new1", "new2"])
# df.append(rows)
# 如果要连接多条记录,append方法的性能不是特别理想,建议使用concat来完成该操作。
# pd.concat((df, rows))
# concat也可以设置ignore_index参数来重新生成索引。
# pd.concat((df, rows), ignore_index=True)
# 删除行
# 删除行与删除列都可以使用drop方法。通过axis的值来控制行标签还是列标签。0:行标签,1:列标签。
df.drop("第一季度", axis=0)
# 也可以删除多行(列)
df.drop(["第一季度", "第四季度"], inplace=True)
# 行与列混合操作
np.random.seed(0)
df = pd.DataFrame(np.random.randint(100, 200,size=(4, 3)), index=["第一季度", "第二季度", "第三季度", "第四季度"],
columns=["苹果", "香蕉", "葡萄"])
display(df)
# 先获取行,再获取列
# df.loc["第一季度"].loc["葡萄"]
# 先获取列,再获取行
# df["香蕉"].loc["第四季度"]
# df["香蕉"].iloc[-1]
# 获取多行多列
# df.loc["第一季度":"第三季度"][["苹果", "葡萄"]]
# df[["苹果", "葡萄"]]
# df.loc["第一季度":"第二季度"]
# 注意在操作时,返回类型的不同,尽管以下两个操作都是返回第1行数据,但是返回数据的类型是不同的。
# 前者返回的是Series类型,而后者返回的是DataFrame类型。因为后者使用的是切片,而切片可能会截取多条数据,
# 因此,会返回DataFrame。(只要使用切片,无论截取多少条数据,一律以DataFrame返回。)
# df.loc["第一季度"]
# df.loc["第一季度":"第一季度"]
# 使用df[行索引:行索引]也能够对行进行切片操作,但是,这种方式既可以传递标签索引,也可以传递位置索引,
# 容易造成混淆,不建议大家使用。建议使用df.loc或df.iloc。
# df["第一季度":"第三季度"]
# df[0:2]
# 布尔数组是对行进行的操作。索引数组是对列进行的操作。
# df[[True, True, False, False]]
# 展示苹果销量 > 150 的记录。
# df[df["苹果"] > 150]
# df[["苹果", "葡萄"]]
# df.loc[["第一季度", "第四季度"]]
df.iloc[[0, 3]]