Pandas数据结构介绍

Series

Series介绍

Series是一种一维的数组型对象,它包含了一个值序列(values)**,并且包含了数据标签,称为索引(index)**。

Series创建

pd.Series(data=None,index=None,dtype=None,name=None,copy=False)

  • data:创建数组的数据,可为array-like, dict, or scalar value

  • index:指定索引

  • dtype:数组数据类型

  • name:数组名称

  • copy:是否拷贝

  • data可为iterable, dict, or scalar value索引默认为range(0,n) 可以通过index指定索引

1
2
3
4
5
6
7
8
9
10
11
12
13
import pandas as pd
import numpy as np

#指定索引 索引可以重复 索引长度和value长度必须一致
s1 = pd.Series([1,2,3,4,5],index=list('abcde'))
print(s1)

#a 1
#b 2
#c 3
#d 4
#e 5
#dtype: int64
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
import pandas as pd
import numpy as np

#可以传入字典
dic = {
'name':'sansan',
'age':18
}
s2 = pd.Series(dic)
print(s2)
#name sansan
#age 18
#dtype: object
#如果有index 则以index指定为主
idex = ['class','age']
print(pd.Series(dic,index=idex))
#class NaN
#age 18
#dtype: object

数据类型根据data自动调整,但是也可以通过dtype指定

1
2
3
4
5
6
7
8
9
10
11
12
import pandas as pd
import numpy as np
#指定数据类型
s3 = pd.Series(np.arange(7),dtype='float')
print(s3)
#0 0.0
#1 1.0
#2 2.0
#3 3.0
#4 4.0
#5 5.0
#6 6.0

使用name参数设置数组名称

1
2
3
4
5
6
7
8
9
import pandas as pd
import numpy as np
#设置Series数组名字 参数name
s4 = pd.Series(np.random.randint(1,10,size=3),index= list('abc'),name='Sansan')
print(s4)
#a 3
#b 3
#c 1
#Name: Sansan, dtype: int32

除此之外,Pandas可以使用Numpy的数组函数。

  • s.dtype # 查看数据类型
  • s.astype() # 修改数据类型
  • s.head(n) # 预览数据前5条
  • s.tail(n) # 预览数据后5条

但是如果需要显示所有数据,则需以下代码。但并不建议使用

1
2
3
4
5
6
7
8
#显示所有列
pd.set_option('display.max_columns', None)

#显示所有行
pd.set_option('display.max_rows', None)

#设置value的显示长度为100,默认为50
pd.set_option('max_colwidth',100)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
import pandas as pd
import numpy as np
#预览数据 默认都为5 可以指定n
s5 = pd.Series(np.random.randint(1,100,size=100))
print(s5.head())
print(s5.tail())
#0 89
#1 5
#2 74
#3 4
#4 63
#dtype: int32
#95 42
#96 38
#97 38
#98 88
#99 68
#dtype: int32

series的索引与值

  • s.index # 查看索引

  • s.values # 查看值序列

  • s.reset_index(drop=False) # 重置索引

    • drop # 是否删除原索引 默认为否

Series索引与切片

  • s[‘标签’] # 通过标签
  • s[‘索引’] # 通过索引
  • s.loc(标签) # 通过标签
  • s.iloc(索引) # 通过索引
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
import pandas as pd
import numpy as np
# pandas底层数据类型是np
s1 = pd.Series(range(1,5))
print(s1.index,s1.values)

#通过行标签获取
s2 = pd.Series(range(5),index=list('abcde'))
print(s2['b'])
print(s2.loc['b'])
#通过索引下标获取
print(s2[1])
print(s2.iloc[1])
#更改
s2['c'] = 5
s2[1] = 10
print(s2)
#切片 也可以使用index
print(s2[:3])
print(s2['a':'c'])
#布尔索引
print(s2[s2>4])

Series运算

  • 共同索引对应为运算,其它填充NaN

  • 没有共同索引时,则全部为NaN

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
import pandas as pd
#索引相同才可以相加
s2 = pd.Series(range(3),index=range(3))
s3 = pd.Series(range(4,7),index=range(3))
print(s2+s3)

#0 4
#1 6
#2 8
#dtype: int64

s4 = pd.Series(range(5,11),index=range(6))
print(s2+s4)

#0 5.0
#1 7.0
#2 9.0
#3 NaN
#4 NaN
#5 NaN
#dtype: float64

s5 = pd.Series(range(5,8),index=range(3,6))
print(s2+s5)

#0 NaN
#1 NaN
#2 NaN
#3 NaN
#4 NaN
#5 NaN
#dtype: float64

DataFrame

DataFrame介绍

DataFrame表示的是矩阵的数据表,它包含已排序的列集合,每一列可以是不同的值类型(数值,字符串,布尔值)。在DataFrame中,数据被存储为一个以上的二维块。

image.png

DataFrame创建

pd.DataFrame(data=None,index=None,columns=None,dtype=None,copy=False)

  • data:创建数组的数据,可为ndarray, dict
  • index:指定索引
  • dtype:数组数据类型
  • copy:是否拷贝
1
2
3
4
5
6
7
8
9
10
11
12
13
14
import pandas as pd
import numpy as np
data = [
{'name':'sansan','age':18,'lesson':'python'},
{'name':'bude','age':20,'lesson':'Java'},
{'name':'jiu','age':22,'lesson':'C++'}
]
#index指定航索引 也可以columns指定列索引
s1 = pd.DataFrame(data,index=list('abc'))
print(s1)
# name age lesson
#a sansan 18 python
#b bude 20 Java
#c jiu 22 C++

重置索引

除了创建时可以指定,我们创建后还可以通过df.reindex()进行重置索引。

  • df**.**reindex(index=None, columns=None, axis=None,fill_value=nan)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
import pandas as pd
import numpy as np

#重置索引
df = pd.DataFrame(np.arange(9).reshape(3,3),index=list('abc'),columns=list('ABC'))
print(df)
print(df.reindex([1,2,3])) #如果重置索引与之前的index没有关系 则全部填充为nan
print(df.reindex(['b','a','c'])) #重置索引与之前的索引完全一致 会根据重置索引进行变动 A B C
# A B C
#a 0 1 2
#b 3 4 5
#c 6 7 8
# A B C
#1 NaN NaN NaN
#2 NaN NaN NaN
#3 NaN NaN NaN
# A B C
#b 3 4 5
#a 0 1 2
#c 6 7 8
1
2
3
4
5
6
7
8
9
import pandas as pd
import numpy as np
#重置列索引 必须指定columns
print(df.reindex(columns=list('BCA')))
#同时重置
print(df.reindex(index=list('cba'),columns=list('CBA')))
#如果索引变多 会变成Nan 但也可以指定添加 fill_value
print(df.reindex(index=list('cbad'),columns=list('CBA')))
print(df.reindex(index=list('cbad'),columns=list('CBA'),fill_value=0))
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
   A  B  C
b 3 4 5
a 0 1 2
c 6 7 8
B C A
a 1 2 0
b 4 5 3
c 7 8 6
C B A
c 8 7 6
b 5 4 3
a 2 1 0
C B A
c 8.0 7.0 6.0
b 5.0 4.0 3.0
a 2.0 1.0 0.0
d NaN NaN NaN
C B A
c 8 7 6
b 5 4 3
a 2 1 0
d 0 0 0

DataFrame基础操作

  • df.shape # 查看数组形状,返回值为元组
  • df.dtypes # 查看列数据类型
  • df.ndim # 数据维度,返回为整数
  • df.index # 行索引
  • df.columns # 列索引
  • df.values # 值
  • d.head(n) # 显示头部几行,默认前5行
  • d.tail(n) # 显示末尾几行,默认后5行
  • d.info() # 相关信息概述
1
2
3
4
5
6
7
8
9
10
11
12
13
data = [
{"name":"amy","age":18,"tel":10086},
{"name":"bob","age":18},
{"name":"james","tel":10086},
{"name":"zs","tel":10086},
{"name":"james","tel":10086},
{"name":"ls","tel":10086},
]

d2 = pd.DataFrame(data)
d2.head()
d2.tail()
d2.info()

DataFrame查数据(索引与切片)

直接使用索引与标签:

类型 描述
df[:索引]或df[:”标签”] 表示对行操作
df[“列标签”]或 df[[“列标签”,”列标签”]] 表示对列进行操作
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
import pandas as pd
import numpy as np

data2 = [
{'name':'sansan','age':18,'lesson':'python'},
{'name':'bude','age':20,'lesson':'Java'},
{'name':'jiu','age':22,'lesson':'C++'},
{'name': 'sansan', 'age': 18, 'lesson': 'python'},
{'name': 'bude', 'age': 20, 'lesson': 'Java'},
{'name': 'jiu', 'age': 22, 'lesson': 'C++'},
]
s1 = pd.DataFrame(data2,index=list('abcdef'))
#行索引取值
print(s1[:2])
print(s1[:'b']) #双闭合区间
#列索引取值 取的每一列都是Series 所以包括行索引的部分 不支持位置索引 只能通过标签索引取值
print(s1['name'])
print(s1[['name','age']])
print(s1.name)
#取name前两行
print(s1[:2]['name'])
print(s1.name[:2])
#取出name 不为jiu的数据
print(s1[s1.name != 'jiu'])
1
2
3
4
5
6
7
     name  age  lesson
a sansan 18 python
b bude 20 Java
c jiu 22 C++
d sansan 18 python
e bude 20 Java
f jiu 22 C++
1
2
3
#取数据 其余数据会变为Nan
s2 = pd.DataFrame(np.arange(16).reshape(4,4),columns=list('ABCD'))
print(s2[s2>5])
1
2
3
4
5
      A     B     C     D
0 NaN NaN NaN NaN
1 NaN NaN 6.0 7.0
2 8.0 9.0 10.0 11.0
3 12.0 13.0 14.0 15.0

使用loc及loc查询数据:

  • df.loc[] 通过轴标签选择数据
  • df.iloc[] 通过整数索引选择数据
类型 描述
df.loc[val] 根据标签索引选择DataFrame的单行或多行
df.loc[:,val] 根据标签索引选择DataFrame的单列或多列
df.loc[val1,val2] 同时选择行和列中的一部分
df.iloc[where] 根据位置索引选择DataFrame的单行或多行
df.iloc[:,where] 根据位置索引选择DataFrame的单列或多列
df.iloc[where_i,where_j] 根据位置索引选择行和列
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
s3 = pd.DataFrame(np.arange(16).reshape(4,4),index=['PHP','JAVA','C++','Python'],columns=list('ABCD'))
#loc 根据标签索引
print(s3.loc['Python',:])
print(s3.loc['Python']) #这种方式只能取行
print(s3.loc[:,'C'])
#取两行
print(s3.loc[['PHP','C++'],:])
#取两列
print(s3.loc[:,['A','C']])
#连续取行
print(s3.loc['PHP':'C++',:])
#连续取列
print(s3.loc[:,'A':'C'])
#iloc取下标索引
print(s3.iloc[2])
#取前1 2 两行
print(s3.iloc[:2])
#取2 3 两列
print(s3.iloc[:,1:3])
#取两行
print(s3.iloc[[0,3],:])
#取两列
print(s3.iloc[:,[0,3]])
#筛选出前三列前三行 且第三行过滤大于3的
print(s3.iloc[:,:3][s3.C>5])

DataFrame修改数据

修改数据主要遵循以下两点:

  • 查询数据
  • 再赋值
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
import pandas as pd
import numpy as np
s3 = pd.DataFrame(np.arange(16).reshape(4,4),index=['PHP','JAVA','C++','Python'],columns=list('ABCD'))
#一行8
s3.loc['PHP'] = 8
print(s3)
#一列9
s3.loc[:,'C'] = 9
print(s3)
#单点变20
s3.loc['Python','B'] = 20
print(s3)
#单点变Nan
s3.loc['C++','B'] = None
print(s3)

注意

Pandas中可以直接赋值np.nan,且赋值当前列数据会自动转为浮点类型。而不是整个数组都转,这主要是因为Pandas数据可以是异质性。

DataFrame新增数据

新增列:df[“新的列标签”] = 值

注意:添加列,则新添加的值的长度必须与其它列的长度保持一致,否则会报错。

插入列:如果需要在数据中插入列,则使用 df.insert(loc, column, value)

  • loc 为插入列的位置
  • column 为插入列的标签
  • value 为插入列的值
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
import pandas as pd
import numpy as np
s3 = pd.DataFrame(np.arange(16).reshape(4,4),index=['PHP','JAVA','C++','Python'],columns=list('ABCD'))
s3.loc['PHP'] = 8
print(s3)
s3.loc[:,'C'] = 9
print(s3)
s3.loc['Python','B'] = 20
print(s3)
s3.loc['C++','B'] = None
print(s3)
#插入列
s3['E'] = 10
print(s3)
#在第2列插入F列表
s3.insert(1,'F',[4,5,6,7])
print(s3)

添加行:df.loc[“新的行标签”,:] = 值

除此之外,我们还可以通过 df.append(df2) 方法添加行,但类似于数组与数组的堆叠拼接。所以df2的列索引必须同df一致。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
import pandas as pd
import numpy as np
s3 = pd.DataFrame(np.arange(16).reshape(4,4),index=['PHP','JAVA','C++','Python'],columns=list('ABCD'))
s3.loc['PHP'] = 8
print(s3)
s3.loc[:,'C'] = 9
print(s3)
s3.loc['Python','B'] = 20
print(s3)
s3.loc['C++','B'] = None
print(s3)
#插入列
s3['E'] = 10
print(s3)
s3.insert(1,'F',[4,5,6,7])
print(s3)
#插入行 append可以直接添加其他数据
s4 = s3.append(s3)
print(s4)

DataFrame删除数据

法1:del df[“列标签”]

法2:df.drop(axis=0,index=None,columns=None,inplace=False)

1
2
3
4
5
6
7
8
9
10
11
12
13
import pandas as pd
import numpy as np
s3 = pd.DataFrame(np.arange(16).reshape(4,4),index=['PHP','JAVA','C++','Python'],columns=list('ABCD'))
#删除列
del s3['C']
print(s3)
s5 = s3.drop(columns='B') #没有删除原本列 需要新对象去接受 接收对象已删除该列
s6 = s3.drop(index='PHP')
print(s5)
print(s6)
#删除A列 通过axis=1指定方向 通过inplace=True指定操作原数据
s3.drop('A',axis=1,inplace=True)
print(s3)

DataFrame算术

实际上,通过 + - * / // ** 等符号可以直接对DataFrame与DataFrame之间或者DataFrame以及Series之间进行运算。但秉承的原则就是对应索引运算,存在索引不同时,返回结果为索引对的并集。

但是实际操作会发现,当存在索引不同时,返回的值自动填充NaN。

使用填充值的算术方法

方法 描述
add 加法(+)
sub 减法(-)
div 除法(/)
floordiv 整除(//)
mul 乘法(*)
pow 幂次方(**)

注意

  • Series使用算术方法,不支持指定填充值

描述性统计的概述和计算

方法 描述
count 非NA值的个数
min,max 最小值,最大值
idxmin,idxmax 最小值,最大值的标签索引
sum 求和
mean 平均值
median 中位数
var 方差
std 标准差
cumsum 累计值
cummin,cummax 累计值的最小值或最大值
cumprod 值的累计积
diff 计算第一个算术差值(时间序列)
pct_change 百分比
corr 按索引对其的值的相关性
cov 协方差

DataFrame排序

  • df.sort_index(axis=0,ascending=True) # 索引排序

    • axis指定轴,默认为0轴
    • ascending为排序方式,默认为True表示升序
  • df.sort_values(by) # 值排序

  • by指定一列或多列作为排序键

    1
    2
    3
    4
    5
    6
    7
    8
    import pandas as pd


    cns = pd.read_csv('./catNames2.csv')
    # print(cns)
    # print(cns[cns['Count_AnimalName']>800])
    counts_sort = cns.sort_values(by='Count_AnimalName',ascending=False) #对value进行排序
    print(counts_sort)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
​```
Row_Labels Count_AnimalName
- 1156 BELLA 1195
9140 MAX 1153
2660 CHARLIE 856
3251 COCO 852
12368 ROCKY 823
... ... ...
6884 J-LO 1
6888 JOANN 1
6890 JOAO 1
6891 JOAQUIN 1
16219 39743 1

[16220 rows x 2 columns]

```

注意

  • by = [col1,col2] 是先给col1排序 当col1有相同值时,col2中按排序顺序再排序

函数应用于映射

  • df.apply(func, axis=0) # 通过 apply 将函数运用到列 或者 行
  • df.applymap(func) # applymap将函数应用到每个数据上