numpy主要是关于矩阵的运算,pandas是关于数据如何处理的相关库
当我们拿到一份数据之后,需要对数据进行相应的处理。pandas底层都调用了numpy。
1. 读取文件
import pandas
food_info = pandas.read_csv('food_info.csv')
print(type(food_info)) # 查看该数据的类
print(food_info.dtypes) # 查看数据中的数据类型
输出结果如下:
<class 'pandas.core.frame.DataFrame'>
NDB_No int64
Shrt_Desc object
Water_(g) float64
Energ_Kcal int64
Protein_(g) float64
Lipid_Tot_(g) float64
Ash_(g) float64
Carbohydrt_(g) float64
Fiber_TD_(g) float64
Sugar_Tot_(g) float64
Calcium_(mg) float64
Iron_(mg) float64
Magnesium_(mg) float64
.......
在numpy中主要使用的是ndarray
核心数据结构,而在pandas
中主要使用的是DataFrame
的核心结构。
在pandas中,对字符型的定义比较特别,不像在numpy中定义字符型为str
,在pandas中使用object
来定义字符型。
- print(food_info.head()),默认显示前5条数据,输出结果如下:
- print(food_info.tail()),默认显示后5条数据。
- print(food_info.columns),获取数据的列名:
Index(['NDB_No', 'Shrt_Desc', 'Water_(g)', 'Energ_Kcal', 'Protein_(g)',
'Lipid_Tot_(g)', 'Ash_(g)', 'Carbohydrt_(g)', 'Fiber_TD_(g)',
'Sugar_Tot_(g)', 'Calcium_(mg)', 'Iron_(mg)', 'Magnesium_(mg)',
'Phosphorus_(mg)', 'Potassium_(mg)', 'Sodium_(mg)', 'Zinc_(mg)',
'Copper_(mg)', 'Manganese_(mg)', 'Selenium_(mcg)', 'Vit_C_(mg)',
'Thiamin_(mg)', 'Riboflavin_(mg)', 'Niacin_(mg)', 'Vit_B6_(mg)',
'Vit_B12_(mcg)', 'Vit_A_IU', 'Vit_A_RAE', 'Vit_E_(mg)', 'Vit_D_mcg',
'Vit_D_IU', 'Vit_K_(mcg)', 'FA_Sat_(g)', 'FA_Mono_(g)', 'FA_Poly_(g)',
'Cholestrl_(mg)'],
dtype='object')
- print(food_info.shape), 表示有多少条数据,多少个数据列
输出结果如下:(8618, 36)
,表示有8618条数据,36列
2. 获取数据
print(food_info.loc[0])
表示获取第0个数据:
NDB_No 1001
Shrt_Desc BUTTER WITH SALT
Water_(g) 15.87
Energ_Kcal 717
Protein_(g) 0.85
Lipid_Tot_(g) 81.11
Ash_(g) 2.11
Carbohydrt_(g) 0.06
Fiber_TD_(g) 0
Sugar_Tot_(g) 0.06
Calcium_(mg) 24
Iron_(mg) 0.02
Magnesium_(mg) 2
Phosphorus_(mg) 24
Potassium_(mg) 24
Sodium_(mg) 643
print(food_info.loc[3:6])
将会获取第3、4、5、6条数据print(food_info['NDB_No'])
根据列名读取数据:输出结果:
0 1001
1 1002
2 1003
3 1004
4 1005
...
8613 83110
8614 90240
8615 90480
8616 90560
8617 93600
Name: NDB_No, Length: 8618, dtype: int64
- 获取某几列数据:
columns=['NDB_No','Copper_(mg)']
a = food_info[columns]
print(a)
输出结果:
NDB_No Copper_(mg)
0 1001 0.000
1 1002 0.016
2 1003 0.001
3 1004 0.040
4 1005 0.024
... ... ...
8613 83110 0.100
8614 90240 0.033
8615 90480 0.020
8616 90560 0.400
8617 93600 0.250
[8618 rows x 2 columns]
3. 选择以(g)
结尾的列名所对应的数据
cols = food_info.columns.tolist()
print(cols)
gram_cols = []
for c in cols:
if c.endswith('(g)'):
gram_cols.append(c)
gram_df = food_info[gram_cols]
print(gram_df)
输出结果如下:
4. 算数运算
4.1 将某列数据进行修改
a = food_info['Iron_(mg)']/1000
print(a)
将Iron_(mg)
数据的值全部除以1000.
4.2 将两列数据进行相乘
a = food_info['Water_(g)'] * food_info['Energ_Kcal']
如果两列数据的维度相等,对应数据位置相乘。
4.3 增加一列
iron_grams = food_info['Iron_(mg)']/1000
print(food_info.shape)
food_info['Iron_(g)'] = iron_grams # 新增一列Iron_(g)
print(food_info.shape)
输出结果如下:
(8618, 36)
(8618, 37)
需要注意的时,新增的样本的维度应该是8618*1
,保证与原始数据维度相同。
4.4 Max Min
max_iron_mg = food_info['Iron_(mg)'].max() # 获取Iron_mg列最大的值
print(max_iron_mg)
min_iron_mg = food_info['Iron_(mg)'].min() # 获取Iron_mg列最小的值
print(min_iron_mg)
5. 排序
food_info.sort_values("Sodium_(mg)", inplace=True) # 将Sodium(mg)从小到大进行排序
print(food_info['Sodium_(mg)'])
food_info.sort_values("Sodium_(mg)", inplace=True, ascending=False) # 将Sodium(mg)从大到小排序
print(food_info['Sodium_(mg)'])
- inplace=True 表示是否将排序后的值返回给一个新的DataFrame。
输出结果如下:
760 0.0
611 0.0
8387 0.0
8607 0.0
629 0.0
...
8184 NaN
8185 NaN
8195 NaN
8251 NaN
8267 NaN
Name: Sodium_(mg), Length: 8618, dtype: float64
276 38758.0
5814 27360.0
6192 26050.0
1242 26000.0
1245 24000.0
...
8184 NaN
8185 NaN
8195 NaN
8251 NaN
8267 NaN
Name: Sodium_(mg), Length: 8618, dtype: float64
可以看出他将原始的索引进行了保留,如果想要丢弃原来的索引,重新构建索引,可以使用reset_index
来进行。代码如下
food_info.sort_values("Sodium_(mg)", inplace=True, ascending=False)
print(food_info['Sodium_(mg)'])
reindex = food_info.reset_index(drop=True)
print('--------------')
print(reindex['Sodium_(mg)'])
输出结果如下:
276 38758.0
5814 27360.0
6192 26050.0
1242 26000.0
1245 24000.0
...
8184 NaN
8185 NaN
8195 NaN
8251 NaN
8267 NaN
Name: Sodium_(mg), Length: 8618, dtype: float64
--------------
0 38758.0
1 27360.0
2 26050.0
3 26000.0
4 24000.0
...
8613 NaN
8614 NaN
8615 NaN
8616 NaN
8617 NaN
Name: Sodium_(mg), Length: 8618, dtype: float64
6. 利用pandas进行数据预处理
数据集使用titanic_train.csv
,对原始数据进行查看:
import pandas as pd
import numpy as np
titanic_train = pd.read_csv('titanic_train.csv')
titanic_train.head()
输出结果如下:
6.1 获取age为空的数据
age = titanic_train['Age']
#print(age[0:10])
age_is_null = pd.isnull(age) # 将age中为空的数据筛选,返回结果为True或者False
age_null_true = age[age_is_null] # 只返回age_is_null=True的数据
print(age_null_true)
print(len(age_null_true)) # 查看缺失值的个数
输出结果如下
6.2 对缺失值进行处理
我们应该对缺失值进行手动处理,如果不去处理缺失值,返回结果会出现报错:
mean_age = sum(titanic_train['Age']) / len(titanic_train['Age']) # 求均值
print(mean_age)
输出结果如下:
nan
原因就是因为数据中包含缺失值。
可以对缺失值进行筛选:
good_ages = titanic_train['Age'][age_is_null == False] # 将缺失值去掉
mean_age = sum(good_ages) / len(good_ages)
print(mean_age)
输出结果如下:
29.69911764705882
或者直接删除缺省值的行:
print(titanic_train.shape)
newdata = titanic_train.dropna(axis=0,subset=['Age', 'Sex'])
print(newdata.shape)
通过使用dropna
函数可以将Age
和Sex
列中所有的缺省值去除,并重新赋值给newdata
6.3 求每个仓位的船票平均价格
6.3.1 普通实现
passenger_classes = [1,2,3]
fares_by_class = {}
for this_class in passenger_classes:
pclass_rows = titanic_train[titanic_train['Pclass'] == this_class]
pclass_fares = pclass_rows['Fare']
fare_for_class = pclass_fares.mean() # 求当前列均值
fares_by_class[this_class] = fare_for_class
print(fares_by_class)
输出结果如下:
{1: 84.15468749999992, 2: 20.66218315217391, 3: 13.675550101832997}
虽然功能实现了,但是略显麻烦。
6.3.2 使用pivot_table实现
python提供了pivot_table
函数,可以计算每个舱位的平均价格:
fares_by_class = titanic_train.pivot_table(index="Pclass", values="Fare", aggfunc=np.mean)
print(fares_by_class)
输出结果如下:
Fare
Pclass
1 84.154687
2 20.662183
3 13.675550
pivot_table
的主要功能就是,统计index='Pclass'
与values='Fare'
之间的关系。
6.3.3 计算舱位Pclass
与是否生存Survived
之间的关系:
survived_by_class = titanic_train.pivot_table(index="Pclass", values="Survived", aggfunc=np.mean)
print(survived_by_class)
输出结果如下:
Survived
Pclass
1 0.629630
2 0.472826
3 0.242363
6.3.4 计算登舱口与价格和生存之间的关系
embarked = titanic_train.pivot_table(index='Embarked', values=['Fare','Survived'], aggfunc=np.sum)
print(embarked)
输出结果如下:
Fare Survived
Embarked
C 10072.2962 93
Q 1022.2543 30
S 17439.3988 217
默认情况下,如果pivot_table不写aggfunc=np.sum,则会按照均值进行计算
7 自定义函数
7.1自定义一个函数可以返回第100行数据
def hundredth_row(column):
hundredth_item = column.loc[99]
return hundredth_item
hundred_row = titanic_train.apply(hundredth_row)
print(hundred_row)
返回结果如下:
PassengerId 100
Survived 0
Pclass 2
Name Kantor, Mr. Sinai
Sex male
Age 34
SibSp 1
Parch 0
Ticket 244367
Fare 26
Cabin NaN
Embarked S
dtype: object
7.2 自定义一个函数可以返回缺失值的个数
def null_count(column):
column_null = pd.isnull(column)
null = column[column_null]
return len(null)
column_null_count = titanic_train.apply(null_count)
print(column_null_count)
返回结果如下:
PassengerId 0
Survived 0
Pclass 0
Name 0
Sex 0
Age 177
SibSp 0
Parch 0
Ticket 0
Fare 0
Cabin 687
Embarked 2
dtype: int64
7.3 自定义一个函数可以对数据进行转换
def which_class(row):
pclass = row['Pclass']
if pd.isnull(pclass):
return "Unknown"
elif pclass == 1:
return "First Class"
elif pclass == 2:
return "Second Class"
elif pclass == 3:
return "Third Class"
classes = titanic_train.apply(which_class, axis = 1)
print(classes)
输出结果如下:
0 Third Class
1 First Class
2 Third Class
3 First Class
4 Third Class
...
886 Second Class
887 First Class
888 Third Class
889 First Class
890 Third Class
Length: 891, dtype: object
Series数据结构
上面所介绍的都是DataFrame结构,首先都是通过pandas.read_csv('food_info.csv')
来获得这个DataFrame
结构,而DataFrame
结构是通过一系列的Series
结构组成的。
使用数据集fandango_score_comparison.csv
,这个数据集是关于电影的评分。
fandango = pd.read_csv('fandango_score_comparison.csv')
series_film = fandango['FILM']
print(type(fandango))
print(type(series_film))
输出结果如下:
<class 'pandas.core.frame.DataFrame'>
<class 'pandas.core.series.Series'>
可以看出这个某一列的数据结构就是series
。
操作series
依然可以通过操作DataFrame
的方式进行操作:
print(series_film[0:5])
返回结果:
0 Avengers: Age of Ultron (2015)
1 Cinderella (2015)
2 Ant-Man (2015)
3 Do You Believe? (2015)
4 Hot Tub Time Machine 2 (2015)
Name: FILM, dtype: object
而series
内部的数据结构是ndarray
,代码如下:
film_Names = series_film.values
print(type(film_Names))
输出结果如下:
<class 'numpy.ndarray'>
说明pandas是封装了numpy,很多操作是把numpy的组合在了一起。