Pandas学习2 --- 数据类型Series、DataFrame

Pandas的数据类型

  • Series(一维数据结构)
  • Dataframe

Series --- 带标签的一维数组

常用的初始化方法:

  • 可迭代对象
  • np数组
  • 字典对象
  • 标量

一、Series

1. Series初始化

导入

import pandas as pd
import numpy as np
s = pd.Series([1, 2, 3])
type(s)
pandas.core.series.Series
s
0    1
1    2
2    3
dtype: int64

通过可迭代对象创建Series

 pd.Series(range(5))
0    0
1    1
2    2
3    3
4    4
dtype: int64

通过numpy数组创建Series

t = np.random.randint(5, 15, size=(8))
pd.Series(t)
0    11
1     9
2     6
3     7
4    11
5    12
6     6
7    14
dtype: int64

通过标量创建

pd.Series(100, index=['a', 5, b'sd'])
a        100
5        100
b'sd'    100
dtype: int64

使用字典自带索引

pd.Series({100:165, 'asdf':961})
100     165
asdf    961
dtype: int64

2. Series数据属性

2.1 索引

获得索引

s = pd.Series([7,8,9], index=[1,2,3])
s.index
Int64Index([1, 2, 3], dtype='int64')
s.index = ['a', 'b', 'c']
s
a    7
b    8
c    9
dtype: int64
可以手动创建Index对象(数量必须匹配)
index = pd.Index(['aaaa', 'bbbb', 'cccc'])
pd.Series([7,8,9], index=index)
aaaa    7
bbbb    8
cccc    9
dtype: int64

2.2 值

返回数据

s.values
array([7, 8, 9])
s
a    7
b    8
c    9
dtype: int64

2.3 尺寸

s.size
3
s.dtype
dtype('int64')

2.4 其他

Series可以指定name

index = pd.Index(['a', 'b', 'c'], name = 'Index名字')
s = pd.Series([1,2,3], index=[1,2,3], name='"Series名字"')
s
1    1
2    2
3    3
Name: "Series名字", dtype: int64

索引可以指定name属性

s.index = index
s
My_Index
a    1
b    2
c    3
Name: "Series名字", dtype: int64

head 和 tail ,默认(n=5)

s.head(2)
1    1
2    2
Name: "Series名字", dtype: int64
s.tail(100)
1    1
2    2
3    3
Name: "Series名字", dtype: int64
test_np = np.random.randint(0, 15, size = 10)
test_np
array([3, 5, 9, 6, 1, 8, 9, 9, 2, 1])
test_pd = pd.Series(test_np)
test_pd
0     6
1    11
2     4
3     3
4     4
5     9
6     4
7     7
8    11
9     5
dtype: int64
test_np[5]
9
test_pd[5]
9
test_np[5] == test_pd[5]
True

3. Series运算

test_pd
0     7
1    12
2     5
3     4
4     5
5    10
6     5
7     8
8    12
9     6
dtype: int64
test_pd + 1
0     8
1    13
2     6
3     5
4     6
5    11
6     6
7     9
8    13
9     7
dtype: int64
test_pd + test_pd
0    14
1    24
2    10
3     8
4    10
5    20
6    10
7    16
8    24
9    12
dtype: int64

Series按照 index 计算,缺失则返回结果NaN(not a number)

s1 = pd.Series([1,2,3], index=[1,2,3])
s2 = pd.Series([1,2,3], index=[2,3,4])
s1 + s2
1    NaN
2    3.0
3    5.0
4    NaN
dtype: float64

使用函数方式运算,如果需要处理不匹配值,那么对Series对象填充索引,指定填充值,并进行运算

s1.add(s2, fill_value=100000)
1    100001.0
2         3.0
3         5.0
4    100003.0
dtype: float64

几个特殊浮点数, 以及空值的判断

s = pd.Series([1, 2, 3, float('NaN'), np.NaN])
s.isnull()
0    False
1    False
2    False
3     True
4     True
dtype: bool

nd 和 pd 在计算时对空值的的处理不同

  • numpy会产生空值()
  • pandas忽略空值
t = np.array([1, 2, 3, float('NaN'), np.NaN])
t.sum()
nan
s.sum()
6.0

4. 提取元素

  • 通过索引提取元素
  • 通过标签数组布尔数组提取元素(推荐)
a = np.array([1, 2, 3])
b = pd.Series(a, index = [0,1,2])
index1 = [0, 1, 2]
index2 = [False, True, True]
b[index1]
0    1
1    2
2    3
dtype: int64
b[index2]
1    2
2    3
dtype: int64

注意:

  • 访问可以使用标签索引,也可以使用位置索引
  • 创建时指定的标签,称为标签索引,如果标签索引是数值类型,替换原先默认的位置索引(位置索引失效)

5. 标签索引(loc)和位置索引(iloc) --- 避免索引混淆

b.loc[0]
1
b.iloc[1]
2
# test_np = np.random.randint(0, 15, size = 10)
test_np = np.arange(15)
test_pd = pd.Series(test_np)

test_pd.loc[4:8].values # 标签索引会前闭后闭
array([4, 5, 6, 7, 8])
test_pd.iloc[4:8].values # 标签索引会前闭后开
array([4, 5, 6, 7])
test_np[4:8] # np索引前闭后开
array([4, 5, 6, 7])
test_np[4:80]
array([ 4,  5,  6,  7,  8,  9, 10, 11, 12, 13, 14])

6. 数值操作

  • 获取值
  • 修改值
  • 增加索引-值
  • 删除索引-值
s = pd.Series([1, 2, 3, float('NaN'), np.NaN])
s.loc['a'] = 'a'
s
0      1
1      2
2      3
3    NaN
4    NaN
a      a
dtype: object
s.drop('a') # 创建新的删除对象
0      1
1      2
2      3
3    NaN
4    NaN
dtype: object
s
0      1
1      2
2      3
3    NaN
4    NaN
a      a
dtype: object
s.drop(['a', 3], inplace=True) # 可以这样子删除,所有的inplace参数都默认为False,即返回新对象
s
0      1
1      2
2      3
4    NaN
dtype: object

9. 其他

  • unique --- 去重,但是不排序
  • value_counts --- 计数
s = pd.Series([1, 10, -2, -5, 20, 10, -5])
s.unique()
array([ 1, 10, -2, -5, 20])
s.value_counts(ascending=True)
 1     1
-2     1
 20    1
 10    2
-5     2
dtype: int64

二、DataFrame类型

1. DataFrame创建

多维数据类型,常用在二维情况,包含行标签和列标签。二维DaraFrame的创建方式如下:

  • 二维数组结构(列表,ndarray,DataFrame等)
  • 字典类型,key为列标签,value为一维数据结构
df1 = pd.DataFrame([[11, 21, 31], [99, 88, 77]])
df2 = pd.DataFrame([[11, 21, 31, 41], [99, 88, 77, 66]])
df1
0 1 2
0 11 21 31
1 99 88 77
print(df1)
    0   1   2
0  11  21  31
1  99  88  77

IPython的扩展内建函数display() 可以把多个数据美化呈现方式

display(df1)
display(df2)
0 1 2
0 11 21 31
1 99 88 77
0 1 2 3
0 11 21 31 41
1 99 88 77 66

DataFrame使用的是列向量,因此通过字典创建,Key是列表签名

di = {
    "名字":['a', 'b', 'c', 'd'],
    '年龄':[32, 23, 45, 76],
    '班级':8,
    '成绩':np.random.randint(0,100,4)
}
df = pd.DataFrame(di)
df
名字 年龄 成绩 班级
0 a 32 31 8
1 b 23 46 8
2 c 45 95 8
3 d 76 67 8

index是行标签, columns是列标签

# df.index = ['张三', '李四', '王五', '李六']
df.columns = ["学生名字", '学生年龄', '学生成绩', '学生班级']
df
学生名字 学生年龄 学生成绩 学生班级
0 a 32 31 8
1 b 23 46 8
2 c 45 95 8
3 d 76 67 8

2. 抽取数据——抽样

从头和尾取数据

df.head(n=2)
名字 年龄 成绩 班级
0 a 32 51 8
1 b 23 53 8
df.tail(n=2)
名字 年龄 成绩 班级
2 c 45 63 8
3 d 76 79 8

随机取样

df.sample(n=2, frac=None, replace=False, weights=None, random_state=None, axis=None) # 默认不放回抽样,抽取1个
名字 年龄 成绩 班级
0 a 32 51 8
3 d 76 79 8
df.sample(n=10, replace=True, random_state=456) # random_state是随机数种子; replace=True 是放回抽样
名字 年龄 成绩 班级
3 d 76 79 8
1 b 23 53 8
3 d 76 79 8
1 b 23 53 8
2 c 45 63 8
3 d 76 79 8
0 a 32 51 8
2 c 45 63 8
3 d 76 79 8
2 c 45 63 8
df.sample(n=10, replace=True, random_state=456) # random_state是随机数种子; replace=True 是放回抽样
名字 年龄 成绩 班级
3 d 76 79 8
1 b 23 53 8
3 d 76 79 8
1 b 23 53 8
2 c 45 63 8
3 d 76 79 8
0 a 32 51 8
2 c 45 63 8
3 d 76 79 8
2 c 45 63 8

3. DataFrame属性

  • index --- 行索引
  • columns --- 列索引
  • values --- 数据,二维ndarray数据
  • shape --- 形状
  • ndim --- 维数
  • dtypes --- 数据类型(ndarray是一个能存储的所有元素的唯一类型,DataFrame每一列一个类型)
df.index
RangeIndex(start=0, stop=4, step=1)
df.columns
Index(['名字', '年龄', '成绩', '班级'], dtype='object')
df.values
array([['a', 32, 51, 8],
       ['b', 23, 53, 8],
       ['c', 45, 63, 8],
       ['d', 76, 79, 8]], dtype=object)
df.shape
(4, 4)
df.ndim
2

返回的数据为Series类型

df.dtypes
名字    object
年龄     int64
成绩     int64
班级     int64
dtype: object

4. 行、列操作:

  • 可以通过index和columns提出特定数据
  • 可以为index和columns创建name
  • 直接中括号索引获取列,loc和iloc获取行(Series)

4.1 获取行、列

di = {
    "名字":['a', 'b', 'c', 'd'],
    '年龄':[32, 23, 45, 76],
    '班级':8,
    '成绩':np.random.randint(0,100,4)
}
df = pd.DataFrame(di)
df
名字 年龄 成绩 班级
0 a 32 68 8
1 b 23 33 8
2 c 45 35 8
3 d 76 11 8

获取一个数据

df.loc[0, '名字']
'a'

获取一行

df[ '名字']
0    a
1    b
2    c
3    d
Name: 名字, dtype: object

df [ ] 访问多列

df[['名字', '年龄']]
名字 年龄
0 a 32
1 b 23
2 c 45
3 d 76

获取一行,每一行是一个Series类型

df.loc[1]
名字     b
年龄    23
成绩    33
班级     8
Name: 1, dtype: object

访问多行

df.loc[[1,2,3]]
名字 年龄 成绩 班级
1 b 23 33 8
2 c 45 35 8
3 d 76 11 8

4.2 增加行、列

4.2.1 获取某一列,Series的索引name为DataFrame列标签名字

df['@'] = [1,2,3,4]
df
名字 年龄 成绩 班级 @
0 a 32 68 8 1
1 b 23 33 8 2
2 c 45 35 8 3
3 d 76 11 8 4

4.2.2 添加一列

df['@']
0    1
1    2
2    3
3    4
Name: @, dtype: int64
df.index
RangeIndex(start=0, stop=4, step=1)
df.index.name = '行索引名'
df.columns.name = '列索引名'
df
列索引名 名字 年龄 成绩 班级 @
行索引名
0 a 32 68 8 1
1 b 23 33 8 2
2 c 45 35 8 3
3 d 76 11 8 4

添加一个求和列

df1 = pd.DataFrame({
    '苹果':[1,2,3],
    '香蕉':[4,5,6],
    '葡萄':[7,8,9],
})
df1['总和'] = df1['苹果'] + df1['香蕉'] + df1['葡萄']
df1
苹果 葡萄 香蕉 总和
0 1 7 4 12
1 2 8 5 15
2 3 9 6 18

4.2.3 删除列

df.pop('@')
行索引名
0    1
1    2
2    3
3    4
Name: @, dtype: int64

4.2.4 获取行

df.drop([1,2], axis='index', inplace=False) #返回新对象,不inplace修改
列索引名 学生名字 学生年龄 学生成绩 学生班级
行索引名
0 a 32 31 8
3 d 76 67 8
df.loc[[2, 3]] # 推荐使用标签名称获取对象
列索引名 学生名字 学生年龄 学生成绩 学生班级
行索引名
2 c 45 95 8
3 d 76 67 8
df.iloc[[2, 3]] # 不推荐使用
列索引名 学生名字 学生年龄 学生成绩 学生班级
行索引名
2 c 45 95 8
3 d 76 67 8

4.2.5 增加一行,需要添加的Series数据必须含有name(对应行标签)

di = {
    "名字":['a', 'b', 'c', 'd'],
    '年龄':[32, 23, 45, 76],
    '班级':8,
    '成绩':np.random.randint(0,100,4)
}
df = pd.DataFrame(di)
row = pd.Series([ 's', 45, 65, 8], name='new', index=['名字', '年龄', '成绩', '班级'])
df.append(row )
名字 年龄 成绩 班级
0 a 32 87 8
1 b 23 74 8
2 c 45 36 8
3 d 76 13 8
new s 45 65 8
di = {
    "名字":['a', 'b', 'c', 'd'],
    '年龄':[32, 23, 45, 76],
    '班级':8,
    '成绩':np.random.randint(0,100,4)
}
dff = pd.DataFrame(di)
row = pd.Series([ 's', 45, 65, 8], name='new', index=['名字', '年龄', '成绩', '班级'])
dff.append(row, ignore_index=True)
名字 年龄 成绩 班级
0 a 32 6 8
1 b 23 8 8
2 c 45 93 8
3 d 76 73 8
4 s 45 65 8

在增加多行的时候,优先使用concat,性能更好。

pd.concat((df, dff), axis=0, ignore_index=False)
名字 年龄 成绩 班级
0 a 32 51 8
1 b 23 53 8
2 c 45 63 8
3 d 76 79 8
0 a 32 6 8
1 b 23 8 8
2 c 45 93 8
3 d 76 73 8
result = pd.concat((df, dff), axis=1, ignore_index=False)
result
名字 年龄 成绩 班级 名字 年龄 成绩 班级
0 a 32 51 8 a 32 6 8
1 b 23 53 8 b 23 8 8
2 c 45 63 8 c 45 93 8
3 d 76 79 8 d 76 73 8

4.2.6 删除l列、行

result.drop(['名字', '班级'], axis=1)
年龄 成绩 年龄 成绩
0 32 51 32 6
1 23 53 23 8
2 45 63 45 93
3 76 79 76 73

4.2.7 混合操作

可以先获取行,也可以现货区列

  • drop方法可以删除行和列;
  • df[索引]针对列操作,不支持位置索引,只支持列标签;
  • df.loc[索引]、df.iloc[索引]针对行操作;
  • df[切片]不推荐【对行操作,既支持位置索引,也支持标签索引; 此外,和第二条冲突,切片索引变成了行操作不利于记忆】
  • df[[列表]] 也存在歧义,如果是【标签数组- 列操作】【布尔数组- 行操作】
df = pd.DataFrame({
    '苹果':[1,2,3],
    '香蕉':[4,5,6],
    '葡萄':[7,8,9],
})
df['总和'] = df['苹果'] + df['香蕉'] + df['葡萄']
df
苹果 葡萄 香蕉 总和
0 1 7 4 12
1 2 8 5 15
2 3 9 6 18
df['苹果'].loc([0])
<pandas.core.indexing._LocIndexer at 0x7fd51e4b37f0>
df[['苹果', '葡萄']].loc[[0,2]]
苹果 葡萄
0 1 7
2 3 9

切片访问行

df.iloc[0:1]
苹果 葡萄 香蕉 总和
0 1 7 4 12
df.iloc[0]
苹果     1
葡萄     7
香蕉     4
总和    12
Name: 0, dtype: int64

4.2.8 标签名,name属性的转换

  • 如果拿出列数据,
  • 如果拿出行数据,
df = pd.DataFrame({
    '苹果':[1,2,3],
    '香蕉':[4,5,6],
    '葡萄':[7,8,9],
})
df['总和'] = df['苹果'] + df['香蕉'] + df['葡萄']
df
苹果 葡萄 香蕉 总和
0 1 7 4 12
1 2 8 5 15
2 3 9 6 18
df.loc[0]
苹果     1
葡萄     7
香蕉     4
总和    12
Name: 0, dtype: int64
df[[True, False, False]]
苹果 葡萄 香蕉 总和
0 1 7 4 12
df['苹果']
0    1
1    2
2    3
Name: 苹果, dtype: int64

5. 计算

df1 = pd.DataFrame(np.arange(24).reshape(4,6))
df2 = pd.DataFrame(np.arange(100, 124).reshape(4,6))

转置

df1.T
0 1 2 3
0 0 6 12 18
1 1 7 13 19
2 2 8 14 20
3 3 9 15 21
4 4 10 16 22
5 5 11 17 23

加法

df1 + df2
0 1 2 3 4 5
0 100 102 104 106 108 110
1 112 114 116 118 120 122
2 124 126 128 130 132 134
3 136 138 140 142 144 146

加法对不齐,产生NaN

df2.index = [0, 1, 3, 4]
df2.columns = [0, 1, 2, 3, 4, 6]
df1 + df2
0 1 2 3 4 5 6
0 100.0 102.0 104.0 106.0 108.0 NaN NaN
1 112.0 114.0 116.0 118.0 120.0 NaN NaN
2 NaN NaN NaN NaN NaN NaN NaN
3 130.0 132.0 134.0 136.0 138.0 NaN NaN
4 NaN NaN NaN NaN NaN NaN NaN
df1.add(df2, fill_value=0)
0 1 2 3 4 5 6
0 100.0 102.0 104.0 106.0 108.0 5.0 105.0
1 112.0 114.0 116.0 118.0 120.0 11.0 111.0
2 12.0 13.0 14.0 15.0 16.0 17.0 NaN
3 130.0 132.0 134.0 136.0 138.0 23.0 117.0
4 118.0 119.0 120.0 121.0 122.0 NaN 123.0

DaraFram 和 Series 加法

--- 行和列操作都可以操作

s = pd.Series([100, 200, 300, 400, 500], index = np.arange(5))
df1
0 1 2 3 4 5
0 0 1 2 3 4 5
1 6 7 8 9 10 11
2 12 13 14 15 16 17
3 18 19 20 21 22 23

默认列对齐

df1 + s
0 1 2 3 4 5
0 100.0 201.0 302.0 403.0 504.0 NaN
1 106.0 207.0 308.0 409.0 510.0 NaN
2 112.0 213.0 314.0 415.0 516.0 NaN
3 118.0 219.0 320.0 421.0 522.0 NaN

也可以行操作

df1.add(s,  axis='index')
0 1 2 3 4 5
0 100.0 101.0 102.0 103.0 104.0 105.0
1 206.0 207.0 208.0 209.0 210.0 211.0
2 312.0 313.0 314.0 315.0 316.0 317.0
3 418.0 419.0 420.0 421.0 422.0 423.0
4 NaN NaN NaN NaN NaN NaN

7. 排序

  • 索引排序
  • 值排序
df = pd.DataFrame(np.arange(24).reshape(4,6), index=[5, 6, 2, 4], columns=[6,1,7,3, 4,2])
df
6 1 7 3 4 2
5 0 1 2 3 4 5
6 6 7 8 9 10 11
2 12 13 14 15 16 17
4 18 19 20 21 22 23
df.sort_index(axis=1, ascending=False) # 列操作,降序操作
7 6 4 3 2 1
5 2 0 4 3 5 1
6 8 6 10 9 11 7
2 14 12 16 15 17 13
4 20 18 22 21 23 19
df.sort_index(axis=0, ascending=False)
6 1 7 3 4 2
6 6 7 8 9 10 11
5 0 1 2 3 4 5
4 18 19 20 21 22 23
2 12 13 14 15 16 17
df.sort_values(5, axis=1, ascending=False, inplace=False) # 行操作,降序操作 ************易混淆*****************
2 4 3 7 1 6
5 5 4 3 2 1 0
6 11 10 9 8 7 6
2 17 16 15 14 13 12
4 23 22 21 20 19 18

8. 统计方法

  • mean / sum / count / median
  • max / min
  • cumsum / cumprod
  • argmax / argmin (所在索引, 老式不推荐)
  • idxmax / idxmin (所在索引,推荐)
  • var / std (标准差, 方差)
  • corr / cov (相关系数, 协方差)
df = pd.DataFrame(np.arange(24).reshape(4,6))
df
0 1 2 3 4 5
0 0 1 2 3 4 5
1 6 7 8 9 10 11
2 12 13 14 15 16 17
3 18 19 20 21 22 23
df.mean(axis='columns')
0     2.5
1     8.5
2    14.5
3    20.5
dtype: float64
df.idxmax()
0    3
1    3
2    3
3    3
4    3
5    3
dtype: int64
df.var
<bound method DataFrame.var of     0   1   2   3   4   5
0   0   1   2   3   4   5
1   6   7   8   9  10  11
2  12  13  14  15  16  17
3  18  19  20  21  22  23>
 df.std
<bound method DataFrame.std of     0   1   2   3   4   5
0   0   1   2   3   4   5
1   6   7   8   9  10  11
2  12  13  14  15  16  17
3  18  19  20  21  22  23>
df.corr()
0 1 2 3 4 5
0 1.0 1.0 1.0 1.0 1.0 1.0
1 1.0 1.0 1.0 1.0 1.0 1.0
2 1.0 1.0 1.0 1.0 1.0 1.0
3 1.0 1.0 1.0 1.0 1.0 1.0
4 1.0 1.0 1.0 1.0 1.0 1.0
5 1.0 1.0 1.0 1.0 1.0 1.0

cov(X,Y) = E( [X - E(X)] [Y - E(Y)] )

df.cov()
0 1 2 3 4 5
0 60.0 60.0 60.0 60.0 60.0 60.0
1 60.0 60.0 60.0 60.0 60.0 60.0
2 60.0 60.0 60.0 60.0 60.0 60.0
3 60.0 60.0 60.0 60.0 60.0 60.0
4 60.0 60.0 60.0 60.0 60.0 60.0
5 60.0 60.0 60.0 60.0 60.0 60.0
import matplotlib.pyplot as plt
%matplotlib inline

img = np.ones((500,500,3))
plt.imshow(img[:,:,0], cmap="gray")
<matplotlib.image.AxesImage at 0x7fd51a5e18d0>

png

a

猜你喜欢

转载自www.cnblogs.com/geoffreyone/p/9925259.html
今日推荐