认识DataFrame数据对象
-
导入pandas包:
import pandas as pd
-
加载读取文件:
-
加载CSV文件
df=pd.read_csv('data/movie.csv')#加载movie.csv文件 df.head()#展示前5条数据
-
加载tsv文件
# 参数1 要加载的文件路径,参数2 sep传入分隔符,默认是',' '\t'制表符 df=pd.read_csv('data/gapminder.tsv',sep='\t') print(df)
-
查看部分数据
根据列名加载部分列数据
加载一列数据
加载一列数据,通过df['列名']
方式获取
country_df = df['country']
# 获取数据前5行
country_df.head()
# 输出结果如下
0 Afghanistan
1 Afghanistan
2 Afghanistan
3 Afghanistan
4 Afghanistan
Name: country, dtype: object
加载多列数据
通过列名加载多列数据,通过df[['列名1','列名2',...]]
;注意这里是两层[]
可以理解为 df[列名的list]
subset = df[['country','continent','year']]
#打印后五行数据
print(subset.tail())
# 输出结果如下
country continent year
1699 Zimbabwe Africa 1987
1700 Zimbabwe Africa 1992
1701 Zimbabwe Africa 1997
1702 Zimbabwe Africa 2002
1703 Zimbabwe Africa 2007
按行加载部分数据
行索引
- 先打印前5行数据 观察第一列
print(df.head())
# 输出结果如下
country continent year lifeExp pop gdpPercap
0 Afghanistan Asia 1952 28.801 8425333 779.445314
1 Afghanistan Asia 1957 30.332 9240934 820.853030
2 Afghanistan Asia 1962 31.997 10267083 853.100710
3 Afghanistan Asia 1967 34.020 11537966 836.197138
4 Afghanistan Asia 1972 36.088 13079460 739.981106
- 上述结果中发现,最左边一列是行号,这一列没有列名的数据是DataFrame的行索引,Pandas会使用行号作为默认的行索引。
通过行索引获取指定行数据
使用
df.loc[n]
传入行索引,来获取DataFrame的部分数据(一行,或多行)
- 获取第一行数据,并打印
print(df.loc[0])
# 输出结果如下
country Afghanistan
continent Asia
year 1952
lifeExp 28.801
pop 8425333
gdpPercap 779.445
Name: 0, dtype: object
- 获取第100行数据,并打印
print(df.loc[99])
# 输出结果如下
country Bangladesh
continent Asia
year 1967
lifeExp 43.453
pop 62821884
gdpPercap 721.186
Name: 99, dtype: object
- 获取最后一行数据
# 通过shape 获取一共有多少行
number_of_rows = df.shape[0]
# 总行数-1 获取最后一行行索引
last_row_index = number_of_rows - 1
# 获取最后一行数据,并打印
print(df.loc[last_row_index])
# 输出结果如下
country Zimbabwe
continent Africa
year 2007
lifeExp 43.487
pop 12311143
gdpPercap 469.709
Name: 1703, dtype: object
使用tail方法获取最后一行数据
- 还可以使用tail方法获取最后一行数据
# tail方法默认输出一行 传入n=1控制只显示1行
print(df.tail(n=1))
# 输出结果如下
country continent year lifeExp pop gdpPercap
1703 Zimbabwe Africa 2007 43.487 12311143 469.709298
- 注意:df.loc 和df.tail 两种方式获得的最后一行数据的类型不同,我们可以打印两种结果的类型
subset_loc = df.loc[0]
subset_head = df.head(n=1)
print(type(subset_loc))
print(type(subset_head))
# 输出结果如下
<class 'pandas.core.series.Series'>
<class ’pandas.core.frame.DataFrame’>
# pandas.core.series.Series 单列(单行)数据对象
# pandas.core.frame.DataFrame 表状数据对象
通过多个指定的行索引的值获取指定多行数据
print(df.loc[[0, 99, 999]])
# 输出结果如下
country continent year lifeExp pop gdpPercap
0 Afghanistan Asia 1952 28.801 8425333 779.445314
99 Bangladesh Asia 1967 43.453 62821884 721.186086
999 Mongolia Asia 1967 51.253 1149500 1226.041130
通过行索引下标使用iloc获取指定数据
- 需要注意的是,
iloc
传入的是索引的序号(行索引下标),loc是索引的标签(行索引的值);在当前案例中,索引标签和索引序号刚好相同,所以使用iloc
和loc
效果是一样的- 并不是所有情况下索引标签=索引序号;例如:在做时间序列分析的时候,有些数据集默认使用日期作为行索引的值
- 此时索引标签(行索引的值)是日期
- 索引序号(行索引下标)依然是0,1,2,3
- 总结:
iloc
: 通过行索引的下标获取行数据loc
: 通过行索引的值获取行数据
- 使用
iloc
获取第一行数据,并打印
print(df.iloc[0])
# 输出结果如下
country Afghanistan
continent Asia
year 1952
lifeExp 28.801
pop 8425333
gdpPercap 779.445
Name: 0, dtype: object
- 使用
iloc
获取第100行数据,并打印
print(df.iloc[99])
# 输出结果如下
country Bangladesh
continent Asia
year 1967
lifeExp 43.453
pop 62821884
gdpPercap 721.186
Name: 99, dtype: object
- 使用iloc时传入-1可以获取最后一行数据,这里-1是下标
print(df.iloc[-1])
# 输出结果如下
country Zimbabwe
continent Africa
year 2007
lifeExp 43.487
pop 12311143
gdpPercap 469.709
Name: 1703, dtype: object
- 返回指定范围的多行数据,注意左闭右开
print(df.iloc[4:7])
# 输出结果如下
country continent year lifeExp pop gdpPercap
4 Afghanistan Asia 1972 36.088 13079460 739.981106
5 Afghanistan Asia 1977 38.438 14880372 786.113360
6 Afghanistan Asia 1982 39.854 12881816 978.011439
- 返回前3行数据,注意左闭右开
print(df.iloc[:3])
# 输出结果如下
country continent year lifeExp pop gdpPercap
0 Afghanistan Asia 1952 28.801 8425333 779.445314
1 Afghanistan Asia 1957 30.332 9240934 820.853030
2 Afghanistan Asia 1962 31.997 10267083 853.100710
- 返回后3行数据,注意左闭右开
print(df.iloc[-3:])
# 输出结果如下
country continent year lifeExp pop gdpPercap
1701 Zimbabwe Africa 1997 46.809 11404948 792.449960
1702 Zimbabwe Africa 2002 39.989 11926563 672.038623
1703 Zimbabwe Africa 2007 43.487 12311143 469.709298
根据行或列获取指定范围的数据
loc和iloc属性既可以用于获取行数据,也可以用于获取列数据
df.iloc[[行索引下标],[列索引下标]]
# 返回第一行,第一列的数据
print(df.iloc[[0],[0]])
print(type(df.iloc[[0],[0]]))
print('='*10)
print(df.iloc[42,0])
print(type(df.iloc[42,0]))
# 输出结果如下
country
0 Afghanistan
<class 'pandas.core.frame.DataFrame'>
==========
Angola
<class 'str'>
df.loc[[行索引值],[列索引值]]
# 返回第一行,第一列的数据
print(df.loc[[0],['country']])
print(type(df.loc[[0],['country']]))
print('='*10)
print(df.loc[42,'country'])
print(type(df.loc[42,'country']))
# 输出结果如下
country
0 Afghanistan
<class 'pandas.core.frame.DataFrame'>
==========
Angola
<class 'str'>
使用loc获取数据中的1列或几列
df.loc[:,[列名]]
,冒号表示所有行
subset = df.loc[:,['year','pop']]
print(subset.head())
# 输出结果如下
year pop
0 1952 8425333
1 1957 9240934
2 1962 10267083
3 1967 11537966
4 1972 13079460
使用iloc获取数据中的1列或几列
df.iloc[:,[列序号]]
subset = df.iloc[:,[2,4,-1]]
print(subset.head())
# 输出结果如下
year pop gdpPercap
0 1952 8425333 779.445314
1 1957 9240934 820.853030
2 1962 10267083 853.100710
3 1967 11537966 836.197138
4 1972 13079460 739.981106
通过range内置函数生成序号,结合iloc获取连续多列数据
- 通过range内置函数取出前5列的数据
tmp_range = list(range(5))
print(tmp_range)
subset = df.iloc[:,tmp_range]
print(subset.head())
# 输出结果如下
[0, 1, 2, 3, 4]
country continent year lifeExp pop
0 Afghanistan Asia 1952 28.801 8425333
1 Afghanistan Asia 1957 30.332 9240934
2 Afghanistan Asia 1962 31.997 10267083
3 Afghanistan Asia 1967 34.020 11537966
4 Afghanistan Asia 1972 36.088 13079460
- 通过range内置函数取出第3、4列的数据
tmp_range = list(range(3,5))
print(tmp_range)
subset = df.iloc[:,tmp_range]
print(subset.head())
# 输出结果如下
[3, 4]
lifeExp pop
0 28.801 8425333
1 30.332 9240934
2 31.997 10267083
3 34.020 11537966
4 36.088 13079460
在 iloc中使用切片语法获取几列数据
- 使用切片语法获取前三列
subset = df.iloc[:,3:6]
print(subset.head())
# 输出结果如下
lifeExp pop gdpPercap
0 28.801 8425333 779.445314
1 30.332 9240934 820.853030
2 31.997 10267083 853.100710
3 34.020 11537966 836.197138
4 36.088 13079460 739.981106
- 获取第0,2,4列,要求使用切片step
# 0:6:2 表示从0列到5列,包含5,但每次跳过1列(选择每2列中的最后1列)
subset = df.iloc[:,0:6:2]
print(subset.head())
print('='*10)
# 对比
print(df.iloc[0,:])
# 输出结果如下
country year pop
0 Afghanistan 1952 8425333
1 Afghanistan 1957 9240934
2 Afghanistan 1962 10267083
3 Afghanistan 1967 11537966
4 Afghanistan 1972 13079460
==========
country Afghanistan
continent Asia
year 1952
lifeExp 28.801
pop 8425333
gdpPercap 779.445
Name: 0, dtype: object
查看所有列的列名
# 通过columns字段获取,返回一个numpy类型的array
print(df.columns.values)
# 通过list表列出
print(list(df))
#df.columns返回index,通过tolist()或者list(df.columns)转换为list类型
print(df.columns.tolist())
# 输出结果如下
['country' 'continent' 'year' 'lifeExp' 'pop' 'gdpPercap']
['country', 'continent', 'year', 'lifeExp', 'pop', 'gdpPercap']
['country', 'continent', 'year', 'lifeExp', 'pop', 'gdpPercap']
行号列号取数据
获取 第1列,第4列,第6列(country,lifeExp,gdpPercap) 中的第1行,第100行和第1000行数据
print(df.iloc[[0,99,999],[0,3,5]])
# 输出结果如下
country lifeExp gdpPercap
0 Afghanistan 28.801 779.445314
99 Bangladesh 43.453 721.186086
999 Mongolia 51.253 1226.041130
行名列名取数据
在实际工作中,获取某几列数据的时候,建议传入实际的列名,使用列名的好处:
- 增加代码的可读性
- 避免因列顺序的变化导致取出错误的列数据
print(df.loc[[0,99,999],['country','lifeExp','gdpPercap']])
# 输出结果如下
country lifeExp gdpPercap
0 Afghanistan 28.801 779.445314
99 Bangladesh 43.453 721.186086
999 Mongolia 51.253 1226.041130
行3.切片列名或列号取数据
可以在loc 和 iloc 属性的行部分使用切片获取数据
- 根据行名、列名取值
print(df.loc[2:6, ['country','lifeExp','gdpPercap']]) # 根据行名、列名取值
# 输出结果如下
country lifeExp gdpPercap
2 Afghanistan 31.997 853.100710
3 Afghanistan 34.020 836.197138
4 Afghanistan 36.088 739.981106
5 Afghanistan 38.438 786.113360
6 Afghanistan 39.854 978.011439
- 根据行号、列号取值
print(df.iloc[2:6, [0,3,5]]) # 根据行号、列号取值
# 输出结果如下
country lifeExp gdpPercap
2 Afghanistan 31.997 853.100710
3 Afghanistan 34.020 836.197138
4 Afghanistan 36.088 739.981106
5 Afghanistan 38.438 786.113360
- 注意两者返回结果的区别
print(df.loc[2:6, ['country','lifeExp','gdpPercap']]) # 根据行名、列名取值
print(df.iloc[2:6, [0,3,5]]) # 根据行号、列号取值
# 输出结果如下,注意输出结果中的差异
country lifeExp gdpPercap
2 Afghanistan 31.997 853.100710
3 Afghanistan 34.020 836.197138
4 Afghanistan 36.088 739.981106
5 Afghanistan 38.438 786.113360
6 Afghanistan 39.854 978.011439
country lifeExp gdpPercap
2 Afghanistan 31.997 853.100710
3 Afghanistan 34.020 836.197138
4 Afghanistan 36.088 739.981106
5 Afghanistan 38.438 786.113360
# 差异原因解析:值切片的原则是左闭右也闭,下标切片的原则是左闭右开
#loc[2:6,...] loc是按值取数,所以行号的值是2到6的都取出
#iloc[2:6,...] iloc是按下标取数,所以行下标是2到5的都取出
分组和聚合计算:
print(df.group(['year','continent'])[['lifeExp','gdpPercap']].mean())
如果想去掉 year continent的层级结构,可以使用reset_index方法(重置行索引):
print(df.groupby(['year','continent'])[['lifeExp','gdpPercap']],mean().reset_index())
基本绘图:
通过plot函数画图:
df.groupby('year')['lifeExp'].mean().plot()