学习pandas,这一篇文章就够了!

学习pandas这一篇文章就够了!

​ pandas的强大相信用过的都觉得很强,对于数据处理而言可以说是必不可缺的。废话少说,开始肝了!

文章目录

一、创建Series和DataFrame

pandas有一维数据,二维和多维,一般我们就只使用一二维

1. 创建Series

​ Series是一维,如下所示:

直接利用列表创建

list_name = ['Alice','Bob','Cindy','Eric','Halen','Grace']
series = pd.Series(list_name)
print(series)

学习pandas,这一篇文章就够了!

可以指定索引,如果不指定就会像上面的例子一样

list_name = ['Alice','Bob','Cindy','Eric','Halen','Grace']
series = pd.Series(list_name,index=['a','b','c','d','e','f'])
print(series)

学习pandas,这一篇文章就够了!

利用字典创建

dict = {"id":1,"name": "Alice", "math": 90, "english": 100}
series1 = pd.Series(dict)
print(series1)

学习pandas,这一篇文章就够了!

2. 创建DataFrame

​ DataFrame是二维数据,以下给出了创建的三种方法,结果都是一样的。


test_dict = {'id':[1,2,3,4,5,6],
             'name':['Alice','Bob','Cindy','Eric','Halen','Grace'],
             'math':[90,99,78,98,97,81],
             'english':[100,100,95,78,45,75]}
data = pd.DataFrame(test_dict,index=list('abcdef'))
print(data)

list_test = [[1,2,3,4,5,6],
             ['Alice','Bob','Cindy','Eric','Halen','Grace'],
             [90,99,78,98,97,81],
             [100,100,95,78,45,75]]
list_test_new = np.array(list_test).T
data2 = pd.DataFrame(list_test_new,index=list('abcdef'),columns=['id','name','math','english'])
print(data2)

list_test = [[1,'Alice',90,100],
             [2,'Bob',99,100],
             [3,'Cindy',78,98],
             [4,'Eric',98,78],
             [5,'Halen',97,45],
             [6,'Grace',81,75]]
data3 = pd.DataFrame(list_test,index=list('abcdef'),columns=['id','name','math','english'])
print(data3)

学习pandas,这一篇文章就够了!

二、基本操作

1. 查

​ 这里的例子就取以上的data为例。

​ 我将用 lociloc为大家举例,

​ loc就是根据行索引和列名定位,iloc就是根据行列的索引定位。

1.1 查找一列或者几列元素(或行)


print(data.loc[:,['name','english']])
print(data.iloc[:,[1,3]])

这里的引号指的是所有,逗号前表示行,逗号后表示列(在这里是指定的列)

学习pandas,这一篇文章就够了!

print(data.loc['a':'d',['id','name','english']])
print(data.iloc[0:4,[0,1,3]])

注意,loc中的由于” : “不是根据索引定位的,所以取Alice到Eric直接写成 ‘a’:’d’ 就可以,但是iloc 是根据索引定位的,取Alice到Eric就是(Alice的索引)到(Eric的索引 + 1)才行

学习pandas,这一篇文章就够了!
print(data['name'])
print(data['name']['b'])

学习pandas,这一篇文章就够了!

这里补充另外一种方法,就是直接在dataframe后面加上 列名和行名,就和loc是一样的, 注意只能是名字,而不是索引。

1.2 查找符合条件的元素


print(data.iloc[:,2]>90)

print(data.iloc[list(data.iloc[:,2]>90),0:3])
print(data.loc[data.iloc[:,2]>90,'id':'math'])

在这里使用了series的 面具用法,意思是找到元素对应的布尔值,然后 输出布尔值为True的,如下:

学习pandas,这一篇文章就够了!

info_bool1 = data.loc[:,'name'].map(lambda x:True if len(x)>4 else False)
info_bool2 = data.iloc[:,1].map(lambda x:True if len(x)>4 else False)
print(info_bool2)
print(data.loc[list(info_bool2),:])
print(data.iloc[list(info_bool2),:])

这里的 mapseries专门的函数,它的作用就是遍历series中的每一个元素,然后在使用 lambda匿名函数对值进行处理。

学习pandas,这一篇文章就够了!

以下这种方法(函数)效果也是一样的

def len_name(x):
    if len(x)>4:
        return True
    else :
        return False
info_bool3 = data.iloc[:,1].map(len_name)print(data.iloc[list(info_bool3),:])

info_bool4 = data.iloc[:,1].map(lambda x:True if len(x)>4 else False)
data_info5 = data.iloc[list(info_bool4),:]
print(data_info5.iloc[list(data_info5.iloc[:,2]>90),:])

学习pandas,这一篇文章就够了!

1.3 获取列名和索引以及修改

(1)获取索引、列名和所有元素值

print(list(data.index))
print(list(data.columns))
print(data.values)
print(data.values.tolist())

学习pandas,这一篇文章就够了!

(2)修改列名

data1 = data.rename(columns={'id':'ID','name':'NAME'})
print(data1)

学习pandas,这一篇文章就够了!

(3)重置索引

df1=data1.reset_index()
print(df1)
df2 = data1.reset_index(drop=True)
print(df2)

学习pandas,这一篇文章就够了!

(4)将dataframe中的某一列设置为索引

df3 = data.set_index('name')
print(df3)print(df3.loc['Bob':'Halen',:])
df4 = df3.set_index('id')print(df4)

​ 将data中的name列设置为索引, 代替了原来的索引,df4在df3的基础上将id设置为索引,代替了原来的name列。

学习pandas,这一篇文章就够了!

1.4 基本信息查看

  1. 查看维度
print(data.shape)
  1. 查看类型
print(data.dtypes)
  1. 转换类型
data.iloc[:,2:] = data.iloc[:,2:].astype('float')
  1. 查看值
test_dict = {'id':[1,2,3,4,5,6],
             'name':['Alice','Alice','panda','Eric','Alice','panda'],
             'math':[90,99,78,98,97,81],
             'english':[100,100,95,78,45,75]}
test_data = pd.DataFrame(test_dict,index=list('abcdef'))

学习pandas,这一篇文章就够了!
print(test_data.iloc[:,1].value_counts())
print(test_data.iloc[:,1].unique())
print(test_data.iloc[:,1].values)

学习pandas,这一篇文章就够了!

2. 增

2.1 增加行

有两种方法增加,

  1. 使用loc
data.loc['new'] = [7,'panda',99,99]
print(data)

​ 注意使用loc时,要将索引名设置为和原来的索引名没有重复的,不然就会修改。

data.loc['b']=[7,'panda',99,99]
print(data)

学习pandas,这一篇文章就够了!
  1. 使用concat连接
data1 = pd.DataFrame([[7,'panda',99,99]],columns=['id','name','math','english'])

data = pd.concat([data,data1],axis=0)
print(data)

学习pandas,这一篇文章就够了!

2.2 增加列

  1. 使用insert 参数为列名的索引,然后为,列名,最后是数据
data.insert(0,'new_col',[11,22,33,44,55,66])
print(data)
  1. 直接定位
data['new_c'] = [11,22,33,44,55,66]
print(data)

data['new_d'] = data.iloc[:,2] - data.iloc[:,3]
print(data)

和增加行一样,都是需要设置独一无二的列名,不然就是修改

  1. 使用concat
data = pd.concat([data,pd.DataFrame([11,22,33,44,55,66],index=list('abcdef'))],axis=1)
print(data)

这几个结果都是一样的,

学习pandas,这一篇文章就够了!

3. 删

print(data.drop(['a','f'],axis=0))
print(data.drop(['id','name'],axis=1))

print(data.drop(labels='c',axis='index'))
print(data.drop(labels=['a','f'],axis=0))
print(data.drop(labels='id',axis='columns'))

​ 重点就是要指定 行或列名

​ 在这里axis=0或者axis=’index’表示行,axis=1或者axis=’columns’表示列

​ 注意有时候不必专门去记忆axis=0和axis=1,因为有些时候axis=0反而表示列,1表示行。

4. 改

​ pandas改值的原理就是利用 loc或者iloc定位之后,然后进行赋值

公式为:

修改行:data.iloc[需要修改的行,:]=赋予新的值
修改列:data.iloc[:,需要修改的列]=赋予新的值
或者使用loc

4.1 改一个值

​ 以下给出三种方式,原理其实都一样,首先定位到判断的那一列,然后进行赋值。


data.loc[data.loc[:,'math']>90,'math']=100
data.iloc[list(data.iloc[:,2]>90),2]=100
data.iloc[data.loc[:,'math']>90,2]=100
print(data)

学习pandas,这一篇文章就够了!

再举一个例子,

data.iloc[data.loc[:,'name'].map(lambda x:len(x)>4),0]='名字很长的id'
print(data)

学习pandas,这一篇文章就够了!

4.2 改多个值

下面就举例,

data.iloc[:,[2,3]] = [0,0]
print(data)

学习pandas,这一篇文章就够了!
data.iloc[3:,:] = ['修改id','修改name','为空','为空']
print(data)

学习pandas,这一篇文章就够了!

data.iloc[:,[2,3]] = data.iloc[:,[2,3]]/10
print(data)

学习pandas,这一篇文章就够了!

condition = list(data.iloc[:,1].map(lambda x:len(x)>4))
data.iloc[condition,[2,3]] = data.iloc[condition,[2,3]]/10
print(data)

学习pandas,这一篇文章就够了!

5. 连接操作

5.1 连接准备

df1 = data.iloc[:,0:2]
df2 = data.iloc[:,2:]
df3 = pd.DataFrame({'math':[89,75,36,59],'english':[94,89,16,47]})

学习pandas,这一篇文章就够了!

5.2 连接说明

不管是横向连接还是纵向连接都需要将连接的列名或者索引名设置为一样的,不然就会新创建一个。下面就举例,

这里是设置索引名的

data = pd.concat([data,pd.DataFrame([11,22,33,44,55,66],index=list('abcdef'))],axis=1)
print(data)

学习pandas,这一篇文章就够了!

这里是不设置索引列名的

data = pd.concat([data,pd.DataFrame([11,22,33,44,55,66])],axis=1)
print(data)

学习pandas,这一篇文章就够了!

同理也是需要设置列名的。

5.3 横向连接

print(df1,'\n',df2)
new_data = pd.concat([df2,df1],axis='columns')
print(new_data)

​ 注意,[df2,df1]有表示先后顺序

学习pandas,这一篇文章就够了!

5.4 纵向连接

new_data2 = pd.concat([df2,df1],axis=0)
print(new_data2)

学习pandas,这一篇文章就够了!

​ 可以看到这里的索引不是一样的,所以可以重置索引

new_data3 = new_data2.reset_index(drop=True)
print(new_data3)

学习pandas,这一篇文章就够了!

6. 排序操作

DataFrame.sort_values(by, axis=0, ascending=True, inplace=False, kind='quicksort', na_position='last')

axis:0或者1,默认0纵向排序,1横向排序
by:str or list of str;如果axis=0,那么by="列名";如果axis=1,那么by="行名";
ascending:布尔型,True则升序,可以是[True,False],即第一字段升序,第二个降序
inplace:布尔型,是否用排序后的数据框替换现有的数据框
kind:排序方法,{'quicksort', 'mergesort', 'heapsort'}, default 'quicksort'
na_position : {'first', 'last'},default 'last',默认缺失值排在最后面
data_sort1 = data.sort_values(by='math',ascending=False)
print(data_sort1)

学习pandas,这一篇文章就够了!

data_sort2 = data.sort_values(by=['math','english'],ascending=[False,False])
print(data_sort2)

学习pandas,这一篇文章就够了!

9. groupby分组操作

  1. 数据准备
data1 = pd.DataFrame({'班级':[1,2,1,1,2,3],
                      '姓名':['pan','panda','panda1','fan','jian','lan'],
                      '数分':np.random.rand(6)*100,
                      '高代':np.random.rand(6)*100})
print(data1)

学习pandas,这一篇文章就够了!
  1. 数据处理 按照班级分类
data2 = data1.groupby('班级')
for i in data2:
    print(i)

学习pandas,这一篇文章就够了!

获取1班的数据

list_data3 = list(data2)
data_1 = list_data3[0][1]
print(data_1)

学习pandas,这一篇文章就够了!

当然这里还可以用iloc或者loc获取

data_1 = data1.iloc[list(data1.iloc[:,0]==1),:]
print(data_1)

8. one-hot编码(独热编码)

​ 在统计一些人的性别的时候,我们需要将其转换为数值,就可以用0和1来代替。同时也带来了问题,是男为1,还是女为1呢,因为有些人认为这会影响男权主义和女权主义,所以就有了one-hot编码,那么它是什么样的呢?

学习pandas,这一篇文章就够了!

这里的男和女这两列就是独热编码。

有几类就有几列,比如说这里只有男和女,那么就有两列。

data = pd.DataFrame(np.arange(16).reshape(4,-1),columns=list('abcd'))
print(data)

学习pandas,这一篇文章就够了!
data_one_hot = pd.get_dummies(data.iloc[:,0],prefix='a')
print(data_one_hot)

这里对 a进行独热编码,a中有4类那么就有4列。

学习pandas,这一篇文章就够了!

当然如果对有排名先后的就不能用独热编码。

这里再补充一个编码方式(机器学习里面的):

from sklearn.preprocessing import LabelEncoder,OneHotEncoder
  1. LabelEncoder 作用就是将每个字符编码。
le = LabelEncoder()
le.fit(['panda','fan','data'])
print(le.transform(['panda','panda','data','fan']))

print(le.fit_transform(['panda','panda','data','fan']))

得到的结果就是 [2 2 0 1]
2. OneHotEncoder 这种方法和 get_dummies效果一样。

ohe = OneHotEncoder()
data = pd.DataFrame(np.arange(16).reshape(4,-1),columns=list('abcd'))
print(ohe.fit_transform(np.array(data.iloc[:,0]).reshape(4,-1)).toarray())

学习pandas,这一篇文章就够了!

三、数据预处理(实战)

1. 导入数据以及清洗数据

​ 导入导出数据就是利用 read_excelread_csv来导入,这里主要就是说明在导入时应该注意参数设置以及修改数据。

​ 这是原始数据:

学习pandas,这一篇文章就够了!学习pandas,这一篇文章就够了!

; (1)导入数据

data2 = pd.read_excel(r'C:\Users\86178\Desktop\成绩信息表.xlsx',header=1)
print(data2)

​ 在这里可以看到我们需要将 第二行的数据作为 表头就用 header=1来指定。

学习pandas,这一篇文章就够了!

(2)修改列名

输出列名就可以看到此时的列名十分复杂,而且有的没有是 unnamed,所以需要将其修改。

print(data2.columns)

学习pandas,这一篇文章就够了!

​ 修改方法(详细可见上 获取列名和索引以及修改):

new_data2 = data2.rename(columns={'学年学期\n(如:2018-2019-2)':'学年学期','Unnamed: 5':'平时成绩1','实验成绩':'平时成绩2','Unnamed: 7':'平时成绩3'})
print(list(new_data2.columns))

学习pandas,这一篇文章就够了!

这样就修改成功了。

(3)删除冗余行

可以看到

学习pandas,这一篇文章就够了!学习pandas,这一篇文章就够了!

开头和末尾存在冗余行,需要将其删除:

new_data3 = new_data2.drop(labels=[0,44],axis=0)
new_data3 = new_data3.reset_index(drop=True)
print(new_data3)

学习pandas,这一篇文章就够了!

2. 类型转换

print(new_data3.dtypes)

学习pandas,这一篇文章就够了!

其中的期中成绩,平时成绩1,平时成绩2,平时成绩3,期末成绩,必须是float或者int型,因为这样才统计计算。同时学生学生学号也不能为float型的,因为不方便读。

转换类型这里给出了两种方法:

new_data3.loc[:,'期中成绩':'期末成绩'] = new_data3.loc[:,'期中成绩':'期末成绩'].astype('float')
print(new_data3.dtypes)
list_columns = ['期中成绩', '平时成绩1', '平时成绩2', '平时成绩3', '期末成绩']
for i in list_columns:
    new_data3[i] = new_data3[i].astype(np.float16)

new_data3['学生学号'] = new_data3['学生学号'].astype('string')
new_data3['学生学号'] = new_data3['学生学号'].map(lambda x:x[0:10])
print(new_data3.dtypes)
print(new_data3['学生学号'])

学习pandas,这一篇文章就够了!

​ 这样不仅仅把学号的格式规范了,同时也把成绩这几列转换为float型了,也方便计算了。

3. 空值处理

(1)查看全局是否存在空值

print(new_data3.isnull())
print(new_data3.isna())

学习pandas,这一篇文章就够了!

当为True时表示为空,反之不为空。但是一般都不这样使用,除非数据少时,这样能直接看出。

print(new_data3.isnull().values.any())

学习pandas,这一篇文章就够了!

这是判断全局是否存在空值,如果为True,表示全局存在空值,否则就没有。

(2)查看每列或每行是否存在空值及数量

print(new_data3.apply(lambda x:x.isnull().values.any()))
print(new_data3.apply(lambda x:x.isnull().sum()))

学习pandas,这一篇文章就够了!学习pandas,这一篇文章就够了!

这里的 apply是dataframe里面专用的遍历每行每列的,和series中的map一样

(3)删除空值

DataFrame.dropna(axis=0, , how='any' ,there=None, subset=None, inplace=False)
函数作用:删除含有空值的行或列
axis:维度.axis=0表示index行,axis=1表示colums列,默认为0
how:"all"表示这一行或列中的元素全部缺失(为nan)才删除这一行或列,"any"表示这一行或列中只要有元素缺失,就删除这一行或列
thresh:行或列中至少保留n个数据。
    当一行中10个数据,当thresh=5,允许有5个空值,大于5的行则删除。
    当thresh=6,允许有4个空值,大于4的行则删除。
    当thresh=8,允许有2个空值,大于2的行则删除。
    当thresh=9,允许有1个空值,大于1的行则删除。
    当thresh=10,允许有0个空值,存在空值的行就删除。
    总结:当thresh的值越大,删除的行就越多。(thresh)+(允许为空值的数)= 行中元素个数

subset:在某列的子集中选择出现了缺失值的列删除,不在子集中的含有缺失值得列或行不会删除(有axis决定是行还是列)。换句话说,指定删除某一列。eg:subset=['name','id']指定这两列。如果存在空值则删除这行。
inplace:新数据是存为副本还是直接在原数据上进行修改

这里是drop的使用方法,重点掌握 thresh和subset,这两个在特定的情况下能更好清理数据。

list_columns = ['期中成绩', '平时成绩1', '平时成绩2', '平时成绩3', '期末成绩']
new_data4 = new_data3.dropna(axis=0,subset=list_columns,thresh=4)
print(new_data4)

针对这里,设定的是,指定成绩这几列,将设置为,thresh=4。表示在 成绩这五列中, 如果存在空值数大于等于3的删除该行,允许在成绩这5列中可以有1个空值,大于1则删除(总数为5,即thresh最高也就是5)。

那么大家有没有想过为什么要怎样设计呢?

如果数据每行中的缺少量过大,则填充起来的可用性也就不大了,所以设计thresh=4,允许有一个空值存在,超过一的行就删除。

当时候数据量缺失不是很大时,还可以才用填充的方式,也就是下面讲的方法

(4)填充空值

DataFrame.fillna(value=None, method=None, axis=None, inplace=False, limit=None, downcast=None, **kwargs)
函数作用:填充缺失值
value:需要用什么值去填充缺失值
axis:确定填充维度,从行开始或是从列开始
method:ffill:用缺失值前面的一个值代替缺失值,如果axis =1. 那么就是横向的前面的值替换后面的缺失值,如果axis=0,那么则是上面的值替换下面的缺失值。backfill/bfill.缺失值后面的一个值
limit:确定填充的个数,如果limit=2, 则只填充两个缺失值

​ 填充方式一般有:

  1. 指定值填充。
print(new_data4.fillna(0))
print(new_data4.fillna(axis=1,method='ffill'))       # 前面一个值代替
print(new_data4.fillna(axis=1,method='bfill'))
  1. 均值填充。 注意,这里的均值填充是值 计算出除去空值外的平均值,并用它去填充空值,而不是加上空值计算出的平均值。
print(new_data4.iloc[:,4:9].apply(lambda x:x.fillna(x.mean())))

指定成绩这五列,计算均值,然后填充。

这里的x.mean()是计算这一列的均值,类似的还有,x.std()计算方差,x.sum()

4. 数据归一化

在我的另一篇文章中有讲到归一化——波士顿房价预测(深度学习)与找到影响房价的决定性因素(最速下降法) 归一化的作用就是消除量纲的影响

在这里还是讲一下,归一化一般有两种方法:

  1. 最大最小归一化学习pandas,这一篇文章就够了! 有两种方法可以实现: 第一种,直接利用公式计算,
new_data6_1 = new_data5.apply(lambda x:(x - x.min())/(x.max() - x.min()))
print(new_data6_1)

学习pandas,这一篇文章就够了! 第二种,调用库计算,这种方法我觉得是很好的,主要是能 还原数据
from sklearn.preprocessing import MinMaxScaler
sc = MinMaxScaler(feature_range=(0,1))
new_data6_2 = sc.fit_transform(new_data5)
print(new_data6_2)

学习pandas,这一篇文章就够了!
print(sc.inverse_transform(new_data6_2))

还原数据主要是 还原结果,这样很方便,在这里直接举例还原原数据。

学习pandas,这一篇文章就够了!

值得提一下的是,这两种方法不管是哪一种 都是对每列归一化(在每列中找到最大最小值计算),而不是全局的,如果对全局归一化那就相当于没有归一化了。

  1. 正态分布标准化 对成正态分布的数据,进行标准归一化

学习pandas,这一篇文章就够了!
new_data7 = new_data5.apply(lambda x:(x-x.mean())/x.std())
print(new_data7)

学习pandas,这一篇文章就够了!

​ 到了这里pandas数据预处理基本上已经结束了,接下来可以去预测,去得出结论等等,这些后面我会继续出文章的。

五、总结

​ pandas的用法有很多,但是这里差不多已经涵盖了大多数,不过总有一些漏网之鱼,哈哈哈。写了好多天终于写完了,希望这篇文章能够帮到你。文章中出现错误的,或者没有写完整的欢迎评轮,我会继续更新的。

​ 你的点赞收藏就是对我最大的鼓励了。

Original: https://blog.csdn.net/Panda4u/article/details/120578280
Author: Panda4u
Title: 学习pandas,这一篇文章就够了!

原创文章受到原创版权保护。转载请注明出处:https://www.johngo689.com/678349/

转载文章受原作者版权保护。转载请注明原作者出处!

(0)

大家都在看

亲爱的 Coder【最近整理,可免费获取】👉 最新必读书单  | 👏 面试题下载  | 🌎 免费的AI知识星球