Pandas之二维数组DataFrame

DataFrame是一个多维数据类型。由于一般使用二维数据,所以,咱们能够将DataFrame理解成相似excel的表格型数据,由多列组成,每一个列的类型能够不一样。Series其实就是一列数组

由于DataFrame是多维数据类型,所以,DataFrame既有行索引,也有列索引。bash

DataFrame建立方式

咱们可使用以下的方式建立(初始化)DataFrame类型的对象(经常使用):数据结构

  • 二维数组结构(列表,ndarray数组,DataFrame等)类型。
  • 字典类型,key为列名,value为一维数组结构(列表,ndarray数组,Series等)。

说明:app

  • 若是没有显式指定行与列索引,则会自动生成以0开始的整数值索引。咱们能够在建立DataFrame对象时,经过index与columns参数指定。
  • 能够经过head,tail访问前 / 后N行记录(数据)。

# 使用二维数据结构建立DataFrame。没有指定行列索引,自动生成行列索引。都是从0开始的天然数
array1 = np.random.rand(3, 5)
df = pd.DataFrame(array1)
print(df)

# 错误,超过了2d。
# df_more_than2d = pd.DataFrame(np.random.rand(3, 3, 3))
          0         1         2         3         4
0  0.877072  0.941101  0.131574  0.056032  0.141660
1  0.129488  0.211658  0.786556  0.477778  0.912969
2  0.624839  0.336306  0.936274  0.581543  0.541653复制代码

# 使用字典来建立DataFrame。一个键值对为一列。key指定列索引,value指定该列的值。
df = pd.DataFrame({"北京":[100, 200, 125, 112], "天津":[109, 203, 123, 112], "上海":[39, 90, 300, 112]})
display(df)
复制代码


# 显示前N条记录
display(df.head(2))
# 显示后N条记录
display(df.tail(2))
# 随机抽取N条记录
display(df.sample(2)) 复制代码


# 建立DataFrame,指定行,列索引。
df = pd.DataFrame(np.random.rand(3, 5), index=["地区1", "地区2", "地区3"], columns=["北京","天津", "上海","沈阳", "广州"])
display(df)复制代码


DataFrame相关属性

  • index 索引
  • columns 列
  • values 值
  • shape 形状
  • ndim 维度
  • dtypes 数据类型

说明:dom

  • 能够经过index访问行索引,columns访问列索引,values访问数据,其中index与columns也能够进行设置(修改)。
  • 能够为DataFrame的index与columns属性指定name属性值。
  • DataFrame的数据不能超过二维。

df = pd.DataFrame(np.random.rand(3, 5), index=["地区1", "地区2", "地区3"], columns=["北京","天津", "上海","沈阳", "广州"])
# 查看idnex, columns, values等属性
display(df.values, type(df.values))  # 返回DataFrame关联的ndarray数组
display(df.index)   # 返回行索引
display(df.columns)  # 返回列索引
array([[0.88915553, 0.09234275, 0.41773469, 0.92490647, 0.13286735],
       [0.85550017, 0.06293159, 0.75023895, 0.01887861, 0.327761  ],
       [0.13309605, 0.98347602, 0.95935583, 0.92139592, 0.48752687]])numpy.ndarrayIndex(['地区1', '地区2', '地区3'], dtype='object')Index(['北京', '天津', '上海', '沈阳', '广州'], dtype='object')复制代码

# 返回形状
display(df.shape)

# 返回维度
display(df.ndim)

# 返回各列的类型信息。
display(df.dtypes)
(3, 5)2北京    float64
天津    float64
上海    float64
沈阳    float64
广州    float64
dtype: object复制代码

DataFrame相关操做

假设df为DataFrame类型的对象。函数

列操做

  • 获取列【哪一个更好些?】
    • df[列索引]
    • df.列索引
  • 增长(修改)列:df[列索引] = 列数据
  • 删除列
    • del df[列索引]
    • df.pop(列索引)
    • df.drop(列索引或数组)

行操做

  • 获取行
    • df.loc 根据标签进行索引。
    • df.iloc 根据位置进行索引。
    • df.ix 混合索引。先根据标签索引,若是没有找到,则根据位置进行索引(前提是标签不是数值类型)。【已不建议使用, 新版本废弃】
  • 增长行:append【屡次使用append增长行会比链接计算量更大,可考虑使用pd.concat来代替】
  • 删除行
    • df.drop(行索引或数组)

行列混合操做:

  • 先获取行,再获取列。
  • 先获取列,在获取行。

说明:ui

  • drop方法既能够删除行,也能够删除列,经过axis指定轴方向。【能够原地修改,也能够返回修改以后的结果。】
  • 经过df[索引]访问是对列进行操做。
  • 经过df[切片]访问是对行进行操做。【先按标签,而后按索引访问。若是标签是数值类型,则仅会按标签进行匹配。】
  • 经过布尔索引是对行进行操做。
  • 经过数组索引是对列进行操做。

这个地方重点区分,极易混淆。
换种方式进行总结:spa

  • 行操做:切片 和 布尔数组
  • 列操做:索引 和 标签数组/位置数组

df = pd.DataFrame(np.random.rand(5, 5), columns=list("abcde"), index=list("hijkl"))
display(df)复制代码


# 获取多个列(返回一个DataFrame,即便只选择一个列)
display(df[["a", "d"]])复制代码


# 删除列
df["e"] = [6, 7, 8, 9, 10]
del df["e"]
df["e"] = [6, 7, 8, 9, 10]     # 把e列加回去
display(df.pop("e"))           # 从df中删除e列,会返回删除的列e
display(df)
复制代码


h     6
i     7
j     8
k     9
l    10
Name: e, dtype: int64复制代码


df2 = df.drop("h", inplace=False, axis=0)
display(df, df2)复制代码


# 先构造一个DataFrame
np.random.seed(100)
df = pd.DataFrame(np.random.rand(5, 5), index=list("abcde"), columns=list("yuiop"))
display(df)复制代码


# 先获取行,再获取列, 其实loc是从高维到低维逐渐定位的。
display(df.loc["c"]["i"])
display(df.loc["c", "i"])
display(df.loc["c"].loc["i"])
display(df.loc["c"])    # loc函数是从高维到低维依次定位的。不能不指定高维,直接定位到低维
display(df.loc[:, "i"])
0.185328219550075060.185328219550075060.18532821955007506y    0.891322
u    0.209202
i    0.185328
o    0.108377
p    0.219697
Name: c, dtype: float64a    0.424518
b    0.825853
c    0.185328
d    0.171941
e    0.817649
Name: i, dtype: float64复制代码

# 先获取列,在获取行。
df["i"].loc["a"] = 3
display(df)

# 标签索引组定位列,而后loc切片行
display(df[["i", "o", "p"]].loc["b":"d"])复制代码


# 若是布尔数组是二维结构,则True对应的位置元素原样显示,False对应位置的元素置为空值(NaN)
display(df > 0.5)
display(df[df > 0.5])
display(df["i"] > 0.5)
display(df[df["i"] > 0.5])
复制代码


df = pd.DataFrame(np.random.rand(5, 5), columns=list("abcde"), index=list("hijkl"))
display(df)
# DataFrame行操做
# 获取行 loc iloc ix
# loc 根据标签获取
# iloc 根据位置获取

# ix 混合索引 先根据标签,而后再根据位置
display(df.loc["i"])
display(df.iloc[1])

# 不建议使用,由于很是容易形成混淆。
display(df.ix["i"])
display(df.ix[1])复制代码


a    0.598843
b    0.603805
c    0.105148
d    0.381943
e    0.036476
Name: i, dtype: float64复制代码
a    0.598843
b    0.603805
c    0.105148
d    0.381943
e    0.036476
Name: i, dtype: float64复制代码
a    0.598843
b    0.603805
c    0.105148
d    0.381943
e    0.036476
Name: i, dtype: float64复制代码
a    0.598843
b    0.603805
c    0.105148
d    0.381943
e    0.036476
Name: i, dtype: float64复制代码

总结

1)选取某一整行(多个整行)或某一整列(多个整列)数据时,能够用df[]、df.loc[]、df.iloc[],此时df[]的方法书写要简单一些。3d

2)进行区域选取时,若是只能用标签索引,则使用df.loc[]或df.ix[],若是只能用整数索引,则用df.iloc[]或df.ix[]。不过我看到有资料说,不建议使用df.ix[],由于df.loc[]和df.iloc[]更精确(有吗?我没理解精确在哪,望告知)。excel

3)若是选取单元格,则df.at[]、df.iat[]、df.loc[]、df.iloc[]均可以,不过要注意参数。  

4)选取数据时,返回值存在如下状况:

若是返回值包括单行多列或多行单列时,返回值为Series对象; 若是返回值包括多行多列时,返回值为DataFrame对象; 若是返回值仅为一个单元格(单行单列)时,返回值为基本数据类型,例如str,int等。

5)df[]的方式只能选取行和列数据,不能精确到单元格,因此df[]的返回值必定DataFrame或Series对象。

6)当使用DataFrame的默认索引(整数索引)时,整数索引即为标签索引。

DataFrame 增删改

df = pd.DataFrame(np.random.rand(5, 5), columns=list("abcde"), index=list("hijkl"))
display(df)

# 增长一行
line = pd.Series([23, 33, 12., 334.22, 200], index=list("abcde"), name="p")
df = df.append(line)
display(df)

# 删除一行
df1 = df.drop(["h", "j"])
display(df1)

# 修改一行
df.loc["k"] = pd.Series([1,1,1,1,1], index=list("abcde"))
display(df)复制代码



DataFrame结构

DataFrame的一行或一列,都是Series类型的对象。
对于行来讲,Series对象的name属性值就是行索引名称,其内部元素的值,就是对应的列索引名称。
对于列来讲,Series对象的name属性值就是列索引名称,其内部元素的值,就是对应的行索引名称。

DataFrame运算

DataFrame的一行或一列都是Series类型的对象。所以,DataFrame能够近似看作是多行或多列Series构成的,Series对象支持的不少操做,对于DataFrame对象也一样适用,咱们能够参考以前Series对象的操做。

  • 转置
  • DataFrame进行运算时,会根据行索引与列索引进行对齐。当索引没法匹配时,产生空值(NaN)。若是不想产生空值,可使用DataFrame提供的运算函数来代替运算符计算,经过fill_value参数来指定填充值。
  • DataFrame与Series混合运算。【默认Series索引匹配DataFrame的列索引,而后进行行广播。能够经过DataFrame对象的运算方法的axis参数,指定匹配方式(匹配行索引仍是列索引)。】

df1 = pd.DataFrame(np.arange(9).reshape(3, 3))
df2 = pd.DataFrame(np.arange(9, 18).reshape(3, 3))
display(df1, df2)
display(df1 + df2)
display(df1 * df2)复制代码


索引排序

Series与DataFrame对象可使用sort_index方法对索引进行排序。DataFrame对象在排序时,还能够经过axis参数来指定轴(行索引仍是列索引)。也能够经过ascending参数指定升序仍是降序。

df = pd.DataFrame(np.random.random((3, 5)), index=[3,1,2], columns=[1,3,5,2,4])
display(df)复制代码


# 指定按照行索引排序
display(df.sort_index(axis=0, ascending=False))复制代码


# 指定按照列索引排序
display(df.sort_index(axis=1, ascending=True))复制代码


df = pd.DataFrame(np.arange(9).reshape(3, 3), index=[3, 1, 2], columns=[6, 4, 5])
display(df)
# 默认根据行索引进行排升序。
df1 = df.sort_index()
display(df1)
# 根据列索引进行排序
df2 = df.sort_index(axis=1)
display(df2)
复制代码

      

# 就地修改,不会返回修改后的结果。
df.sort_index(inplace=True)
display(df)
# 默认为升序排序,能够指定为降序排序。
df3 = df.sort_index(ascending=False, axis=1)
display(df3)
复制代码

   

值排序

Series与DataFrame对象可使用sort_values方法对值进行排序。

df = pd.DataFrame([[1,3, 2], [5, 2, 4], [2, 4, 3]], index=[1,3,2], columns=list("cab"))
display(df)

# 按照列排序,指定顺序
df1 = df.sort_values("c", ascending=False)
display(df1)

# 按照行排序,指定顺序
df2 = df.sort_values(1, axis=1, ascending=False)
display(df2)

# 值排序
df = pd.DataFrame([[1, 3, 300], [66, 5, 100], [1, 3, 400]])
display(df)

# 根据第2列排升序
df1 = df.sort_values(2)
display(df1)

# 根据第1行排降序
df2 = df.sort_values(1, axis=1, ascending=False)
display(df2)
复制代码

DataFrame索引对象Index

Series(DataFrame)的index或者DataFrame的columns就是一个索引对象。

  • 索引对象能够向数组那样进行索引访问。
  • 索引对象是不可修改的。

DataFrame统计相关方法

  • mean / sum / count
  • max / min
  • cumsum / cumprod
  • argmax / argmin
  • idxmax / idxmin
  • var / std
相关文章
相关标签/搜索