本文作为个人的学习笔记和代码模板整理,仅供参考。
主要包括:pandas基本数据结构、pandas数据基本操作、操作案例。
用到的库:
import numpy as np
import pandas as pd
目录
一、pandas数据结构
维数 | 名称 | 描述 |
---|---|---|
1 | Series | 带标签的一维同构数组 |
2 | DataFrame | 带标签的,大小可变的,二维异构表格 |
1.Series
1.1 基本概念
带标签(index)的一维数组。用pd.Series(data, index=index, name='str')创建。
data支持整数、浮点数、字符串、Python 对象等类型的数据。(注意,data是标量值时,必须提供索引index,Series
按索引长度重复该标量值)
index是轴标签列表,data是多维数组时,index 长度必须与 data 长度一致;没有指定 index
参数时,创建数值型索引,即 [0, ..., len(data) - 1]。
name是名称属性
Series 还可以直接用字典实例化,字典的key作为index,value作为data。
1.2 基本操作
这里不具体展开。仅需知道Series可以用与numpy数组类似的方法操作,也可以用类似字典的方法操作(主要指下标访问操作)。
值得一提的是Series与numpy相似但不完全一样的矢量操作。两者在操作时都不用循环每个值,Series 也支持大多数 NumPy 多维数组的方法。但是区别在于Series 之间的操作会自动基于标签对齐数据。
s1 = {0:1,'1':2,'A':3}
s2 = [1,2,3,4]
s1 = pd.Series(s1) #由字典构建Series
s2 = pd.Series(s2) #由列表构建Series,index缺省则默认0,1,2...
print(s1,'\n',s2,'\n',s1+s2)
s1+s2的输出结果如下。可以看到只有相同的索引int(1)的元素得到了运算结果,其他未能对齐的标签对应的值为NaN。
0 2.0
1 NaN
2 NaN
3 NaN
1 NaN
A NaN
dtype: float64
2.DataFrame
2.1 基本概念
DataFrame 是由多种类型的列构成的二维标签数据结构,类似于 Excel表,或 Series 对象构成的字典。构造函数pd.DataFrame(data,index=index, columns=columns)
data支持一维ndarray、列表、字典、Series 字典、二维numpy.ndarray、Series、DataFrame等多种类型输入数据。(有趣的的是可以由DataFrame递归的构成)
index(行标签)和 columns(列标签)可选。缺省为0,1,2...应注意Series 字典加上指定索引时,会丢弃与传递的索引不匹配的所有数据。
可由Series 字典或字典、多维数组字典、列表字典、元组字典、多维数组等创建。具体代码见下一部分pandas数据基本操作。
二、pandas基本操作
1.生成DataFrame
由列表或numpy数组生成DataFrame,指定行和列的索引
# 由列表或numpy数组生成DataFrame,指定行和列的索引
# 设置行列索引
row_index = [1,2,3,4,5]
col_index = list('name age location email'.split(' '))
# 可以采用遍历的方法设置表格内容,当然也可以用其他方式
contain = []
for i in range(len(row_index)):
row = []
for j in range(len(col_index)):
row.append(f'第{i}行第{j}列的内容')
contain.append(row)
# 构造DataFrame
df = pd.DataFrame(contain,index=row_index, columns=col_index)
print(df)
用字典、多维数组字典、列表字典、字典列表生成
# 用 Series 字典或字典生成 DataFrame
df = {'one': pd.Series([1., 2., 3.], index=['a', 'b', 'c']),
'two': pd.Series([1., 2., 3., 4.], index=['a', 'b', 'c', 'd'])}
df = pd.DataFrame(d)
# 用多维数组字典、列表字典生成 DataFrame
d = {'one': [1., 2., 3., 4.],
'two': [4., 3., 2., 1.]}
pd.DataFrame(d)
# 用列表字典生成 DataFrame
pd.DataFrame([{'a': 1, 'b': 2}, {'a': 5, 'b': 10, 'c': 20}])
2.表格操作
1.表格的变换
# 表格的变换
import pandas as pd
import numpy as np
'''判断数据是何种表:
看其列的内容:每一列是否是一个独立的参数。如果每一列都是独立的参数,
那就是一维数据列表;如果每一列都是同类参数,那就是二维数据列表。
'''
df = pd.DataFrame({'X':['A','B','C'],'2022':[1,3,4],'2023':[3,8,6]})
print(df)
# 二维表转换为一维表,绘图数据常用
df_melt = pd.melt(df, id_vars='X', var_name='year', value_name='value')
#id_vars标识观测的变量,var_name保存原始变量的变量名(去掉名字默认variable)
print(df_melt)
# 逆操作,一维展二维
df_pivot = df_melt.pivot_table(index='X', columns='year', values='value')
# df_pivot = df_pivot.reset_index()
print(df_pivot)
输出:
X 2022 2023 0 A 1 3 1 B 3 8 2 C 4 6 X year value 0 A 2022 1 1 B 2022 3 2 C 2022 4 3 A 2023 3 4 B 2023 8 5 C 2023 6 year 2022 2023 X A 1 3 B 3 8 C 4 6
2.变量的变换
import pandas as pd
import numpy as np
'''
对数据框某列的每个元素都进行运算处理,从而产生并添加新的列
'''
df = pd.DataFrame({'X':['A','B','C'],'2022':[1,3,4],'2023':[3,8,6],'2024':[2,3,5]})
df_melt = pd.melt(df, id_vars='X', var_name='year', value_name='value')
# 变换数据类型
df_melt['year'] = df_melt['year'].astype(int)
print(df_melt.info())
# 直接对每列操作
df['2022'] = df['2022']+2
# 使用transform或apply函数,结合lamdba,进行更复杂操作
df['sum'] = df.apply(lambda x:x['2022']+x['2023'],axis=1)
df['Sum'] = df.apply(lambda x:x['2022':'2024'].sum(), axis=1)
df_melt['value2'] = df_melt.apply(lambda x:x['value']*2 if x['year']=='2022' else x['value'], axis=1)
# 这里的if else应视为运算符,else语句不可省略;axis选对行/列操作
# 按行求和、按列求和
df_rowsum = df[['2022','2023','2024']].apply(lambda x:x.sum(),axis=1)
df_colsum = df[['2022','2023','2024']].apply(lambda x:x.sum(),axis=0)
print(df,'\n',df_melt)
3.表格的排序
# 表格的排序
import pandas as pd
import numpy as np
'''
使用sort_values()函数,根据数据框的某列数值对整个表进行排序。
其中,ascending=False表示根据df的value列做降序处理
'''
df = pd.DataFrame({'X':['A','B','C'],'2022':[1,3,4],'2023':[3,8,6],'2024':[2,3,5]})
df_melt = pd.melt(df, id_vars='X', var_name='year', value_name='value')
data1 = df_melt.sort_values(by='value',ascending=True)
print(data1)
data2 = df_melt.sort_values(by=['year','value'], ascending=False)
print(data2)
4. 表格的拼接与融合
# 表格的拼接与融合
import pandas as pd
import numpy as np
'''拼接:
在已有数据框的基础上添加新的行/列,或者横向/纵向添加另外一个表格。
此时我们需要使用pd.concat()函数或者append()函数实现该功能
'''
df1 = pd.DataFrame(dict(x=['a','b','c'],y=[1,2,3]))
df2 = pd.DataFrame(dict(x=['a','b','c','d'],z=[7,6,4,2]))
df3 = pd.DataFrame(dict(x=['g','h'],y=[8,0]))
# 横向拼接添加列,可以注意到真的只拼接,没对齐
data_1 = pd.concat([df1,df2],axis=1,join='inner') # inner会丢弃含缺失值的表格
print(data_1)
data_1 = pd.concat([df1,df2],axis=1,join='outer') # 默认是outer
print(data_1)
# 纵向拼接添加行
data_2 = pd.concat([df1,df3,df2],axis=0)
print(data_2)
# 逆操作drop
data_1.drop(labels='z',axis=1,inplace=True)# inplace=False,默认该删除操作不改变原数据,而是返回一个执行删除操作后的新DataFrame
print(data_1)
'''融合:
依据一个共同的列(common key)作融合
'''
data_merage = pd.merge(left=df1,right=df2,how='left',on='x')
print(data_merage)
# 参数的名字很明白,left right设置两个源表的左右位置关系
# how设置不完全对齐时融合方式 ,'left'/'right'只保留左/右表所有数据,'inner'公共,'outer'所有
# on设置按哪列对齐,也可用['列名1','列名2']表示多列匹配
data_merage = pd.merge(left=df1,right=df3,how='outer',on='x',suffixes=['.1','.2'])
# 如果合并过程中两表有共同列名但值不同,就可以用suffixes给每个表的重复列名增加后缀
print(data_merage)
5.表格的分组操作
# 表格的分组操作
import pandas as pd
import numpy as np
df = pd.DataFrame({'X':['A','B','C','A','C'],'2022':[1,3,4,2,1],'2023':[3,8,6,2,2]})
df_melt = pd.melt(df, id_vars='X', var_name='year', value_name='value')
'''
分组操作:groupby()
接收的参数是列名或列名的列表
返回的不是分组后的数据框,不能直接输出
'''
#print(df_melt.groupby('year'))>>><pandas.core.groupby.generic.DataFrameGroupBy object at 0x0000020C543D2DF0>
# 分组求均值、方差等
df_group_mean = df_melt.groupby(['year','X'],as_index=False).mean() # 注意这里多重分组的语法
df_group_std = df_melt.groupby(['year','X'],as_index=False).std()
print(df_group_mean,'\n',df_group_std)
三、文件操作实例
数据为Kaggle经典题目房价预测数据集。
# 读入数据
train_data = pd.read_csv('kaggle_house/train.csv') # shape (1460, 81)
test_data = pd.read_csv('kaggle_house/test.csv') # shape (1459, 80)
# 数据拼接
all_features = pd.concat((train_data.iloc[:, 1:-1], test_data.iloc[:, 1:]))
# ===== 预处理=============================================================
# 连续数值标准化
numeric_features = all_features.dtypes[all_features.dtypes != 'object'].index
all_features[numeric_features] = all_features[numeric_features].apply(
lambda x: (x - x.mean()) / (x.std()))
all_features[numeric_features] = all_features[numeric_features].fillna(0)# 标准化后,每个数值特征的均值变为0,所以可以直接用0来替换缺失值
# 离散数值转指示特征
# dummy_na=True将缺失值也当作合法的特征值并为其创建指示特征
all_features = pd.get_dummies(all_features, dummy_na=True) # shape变成(2919, 331)
# 再把train和test分开取出来,转换为tensor
n_train = train_data.shape[0]
train_features = torch.tensor(all_features[:n_train].values, dtype=torch.float)
test_features = torch.tensor(all_features[n_train:].values, dtype=torch.float)
train_labels = torch.tensor(train_data.SalePrice.values, dtype=torch.float).view(-1, 1)
参考资料:
《Python数据可视化之美:专业图表绘制指南(全彩)》 张杰 电子工业出版社
pandas数据合并之一文弄懂pd.concat() - 知乎 (zhihu.com)
《深入浅出Pandas:利用Python进行数据处理与分析》 李庆辉 机械工业出版社