操作对象
Series
pd.Series( data,index,dtype,name,copy)
Series 是一种类似于一维数组的对象,由下面两部分组成:
- data:一维数据,可迭代对象。可以包含缺失数据,Pandas 使用NaN(Not a Number)来表示缺失或无值
s = pd.Series(list('abc')) #列表
a = pd.Series(np.arange(3)) #数组
d = pd.Series({'a': 1,'b': 2,'c': 3}) #字典
- index:数据索引。每个 Series 都有一个索引,它可以是整数、字符串、日期等类型。如果不指定索引,Pandas 将默认创建一个从 0 开始的整数索引。
a = pd.Series(np.arange(3),index=list('abc'))
a.c #非数字索引时,可以直接对象.索引
a['c'] #2 数字索引不能对象.索引,可以对象[number]
a[['b','c']] #也可以传索引列表,返回新的Series对象
顾名思义,我们在创建 series 对象时,需要传递一组数据,该数据大多数时候是可迭代对象。
PS:
Series支持切片
a = pd.Series(np.arange(3),index=list('abc'))
a['a':'c'] #非数字索引左闭右闭,取a b c
d = pd.Series(np.arange(3))
d[0:2] #数字索引左闭右开,只取0 1
DataFrame
DataFrame 是 Pandas 的核心数据结构,用于以表格形式和处理数据,类似提供电子表格或数据库表格,是一个二维的数据结构,可以理解由多个Series对象组成
pd.DataFrame( data, index, columns, dtype, copy)
- data: 可迭代对象,可以是 ndarray,series,list,dict,标量以及一个 DataFrame
- index:行标签,如果没有传递 index 值,则默认行标签是 np.arange(n),n 代表 data 的元素个数。
- columns:列标签,如果没有传递 columns 值,则默认列标签是 np.arange(n)
df = pd.DataFrame(np.arange(6).reshape(3,2),index=list('abc'),columns=list('AB')) #二维数组,指定行列索引
df1 = pd.DataFrame(pd.Series(np.arange(6),index=list('abcdef')),columns=list('B')) #一维Series对象,由Series指定行索引。如果dataframe和Series行索引不一致,最终导致DataFrame值维NAN
print(df,df1)
常用函数
apply()
apply 是 pandas 中的一个非常强大的函数,它可以对 Series 或 DataFrame 的数据进行操作。该函数主要用于当没有现成的函数可以直接完成任务时,你可以使用 apply 将自定义函数应用于数据,它可以对数据进行逐行或逐列的操作,非常适合进行复杂的、自定义的数据处理。
PS:apply默认是按列操作
# apply 是一个非常灵活的函数,可以应用对象是Servies或者DataFrame对象
DataFrame.apply(func, axis=0, raw=False, result_type=None, args=(), **kwds)
Series.apply(func, convert_dtype=True, args=(), **kwds)
- func: 要应用的函数。
- axis: 默认为0。对于DataFrame,axis=0表示应用函数到每一列,axis=1表示应用函数到每一行。
- raw: 默认为False。确定是否将数据转换为Python原生类型。
- result_type: 默认为None。这可以是expand、reduce、broadcast或None之一,它决定了返回的数据类型。
- args: 传递给func的位置参数的元组。
e.g:
df = pd.DataFrame(np.arange(6).reshape(3,2),index=list('abc'),columns=list('AB'))
print(df)
#自定义函数
def cal(x):
return x**2+x*2
ap = df.apply(cal,axis=1) #指定按行操作
示例结果: e.g:
data = {
'商品名称':['电脑','照相机','手机','ps5'],
'销售价格':[10000,12000,7000,4000]
}
# 13%的商品税额
df2 = pd.DataFrame(data)
# 第一种方法
print(df2['销售价格']*0.13)
# 第二种方式
df2['商品税额'] = df2['销售价格'].apply(lambda x:x*0.13) #Series对象.apply
df2
示例结果:map()
map方法主要用于对 Series 对象中的每个元素应用一个指定的函数或映射关系。它通常用于数据清洗和转换,比如将字符串转换为其他格式,或者根据一个映射字典将值替换为新的值。
Series.map(arg)
- arg:函数、字典或其他映射关系。指定应用于Series每个元素的映射规则。
- na action: None或ignore,默认为None。指定遇到缺失值(NaN)时的处理方式。如果设置为ignore,则忽略NaN值,不将其传递给映射关系
e.g:
data = pd.DataFrame({
'name':['A1','B1','C1','D1'],
'gender':['F','M','F','M'],
'age': [11,12,13,14]
})
dict_gender = {
'F': '男',
'M': '女'
}
data['gender_dec'] = data['gender'].map(dict_gender) #data['gender']这一列Series对象应用字典映射
#结果
name gender age gender_dec
0 A1 F 11 男
1 B1 M 12 女
2 C1 F 13 男
3 D1 M 14 女
def age_cal(x):
return x*2
data['new_age'] = data['age'].map(age_cal) #data['age']这一列Series对象应用自定义函数,再写入新的一列‘new_age’
data
#结果:
name gender age gender_dec new_age
0 A1 F 11 男 22
1 B1 M 12 女 24
2 C1 F 13 男 26
3 D1 M 14 女 28
计算描述统计
常用方法
设置索引set_index
data = {
"名字":["Lcuy",'Tony','Tom','Jack'],
'数学':[85,92,78,65],
"英语":[76,88,92,72],
"历史":[90,82,68,56]
}
df3 = pd.DataFrame(data)
# 为了确保能正常计算, 需要设置名字为索引列
df4 = df3.set_index('名字')
print(df3)
print(df4) #设置这一列为索引值,在科学计算时这一列就不会再参与计算,而是作为索引
idxmax
返回一个 Series,其中每个元素表示该列最大值所在的索引
print(df4.idxmax()) #返回每一列最大值所在索引(index,columns)
#结果
数学 Tony
英语 Tom
历史 Lcuy
科学计算常用方法
科学计算方法比较多,在使用到时可单独查询
在计算时,如果遇到不可计算的列,如字符串列,会自动忽略
平均值
mean()函数是 pandas DataFrame 和 Series 对象的一个方法,用于计算指定轴上的平均值。默认情况下,它沿着列(即轴0)计算平均值。
data = {
"名字":["Lcuy",'Tony','Tom','Jack'],
'数学':[85,92,78,65],
"英语":[76,88,92,72],
"历史":[90,82,68,56]
}
df3 = pd.DataFrame(data)
# 为了确保能正常计算, 需要设置名字为索引列
df4 = df3.set_index('名字')
print(df4.mean())
#示例结果
数学 80.0
英语 82.0
历史 74.0
dtype: float64
中位数
median()函数在pandas中主要用于计算DataFrame或Series的中位数。对于Series,它会直接返回该Series的中位数;对于DataFrame,则可以指定轴(axis)来计算每行或每列的中位数。
print(df4.median())
标准差
std()函数是 pandas 库中 series 和 DataFrame 对象的一个方法,用于计算数据集的标准差。标准差是衡量数据分布离散程度的重要指标,反映了数据点与其均值之间的平均距离。
print(df4.std())
协方差
cov()函数用于计算数据集中不同列之间的协方差。在概率论和统计学中用于衡量两个变量的总体误差。 如果两个变量的变化趋势一致,即其中一个大于自身的期望值,另外一个也大于自身的期望值,那么两个变量之间的协方差就是正值。如果两个变量的变化趋势相反,即其中一个大于自身的期望值,另外一个却小于自身的期望值,那么两个变量之间的协方差就是负值。
print(df4['数学'].cov(df4['英语']))
相关性
相关性,是指两个变量的关联程度。一般地,从散点图上可以观察到两个变量有以下三种关系之一:两变量正相关、负相关、不相关
print(df4['数学'].corr(df4['英语']))
数据处理
dropna
在数据分析的过程中,经常遇到数据集中存在缺失值的情况。dropna()函数可以根据指定的条件删除包含缺失值的行或列
DataFrame.dropna(axis=0, how='any', thresh=None, subset=None, inplace=False)
- axis:可选参数,表示删除行还是列。默认值为0,表示删除包含缺失值的行;设置为1表示删除包含缺失值的列。
- how:可选参数,表示删除的条件。默认值为’any’,表示只要存在一个缺失值就删除整行或整列;设置为’all’表示只有当整行或整列都是缺失值时才删除。
data = {
'月份':['1月','2月','3月','4月','5月'],
'房租':[2000,2000,2000,2000,2000],
'水电':[300,280,None,310,290],
'餐费':[500,None,480,600,560],
'交通':[150,140,150,None,None]
}
df5 = pd.DataFrame(data)
# 只要有一个缺失值,则删除包含缺失值的行
df6 = df5.dropna(how='any')
# 只要这一行全部是缺失值,则删除包含缺失值的行
df7 = df5.dropna(how='all')
- thresh:可选参数,表示在删除之前需要满足的非缺失值的最小数量。如果行或列中的非缺失值数量小于等于thresh,则会被删除。
data = {
'月份':['1月','2月','3月','4月','5月'],
'房租':[2000,2000,2000,2000,2000],
'水电':[300,280,None,310,290],
'餐费':[500,None,480,600,560],
'交通':[150,140,150,None,None]
}
df5 = pd.DataFrame(data)
print(df5)
print(df5.dropna(thresh=4,axis=1)) #至少需要4个非缺失值才保留行或列,交通列会被删除
- subset:可选参数,用于指定要检查缺失值的特定列名或行索引。
print(df5.dropna(subset=['交通','水电'])) #只在交通水电列里检查
- inplace:可选参数,表示是否对原始数据进行就地修改。默认值为False,表示不修改原始数据,而是返回一个新的数据框。
填充fillna()
pandas中fillna()方法,能够使用指定的方法填充NA/NaN值。
fillna(value=None, method=None, axis=None, inplace=False, limit=None, downcast=None, **kwargs)
value:用于填充的空值的值。
method: {‘backfill’, ‘bfill’, ‘pad’, ‘ffill’, None}, default None。定义了填充空值的方法, pad / ffill表示用前面行/列的值,填充当前行/列的空值, backfill / bfill表示用后面行/列的值,填充当前行/列的空值。
axis:轴。0或’index’,表示按行删除;1或’columns’,表示按列删除。
inplace:是否原地替换。布尔值,默认为False。如果为True,则在原DataFrame上进行操作,返回值为None。
limit:int, default None。如果method被指定,对于连续的空值,这段连续区域,最多填充前 limit 个空值(如果存在多段连续区域,每段最多填充前 limit 个空值)。如果method未被指定, 在该axis下,最多填充前 limit 个空值(不论空值连续区间是否间断)
downcast:dict, default is None,字典中的项为,为类型向下转换规则。或者为字符串“infer”,此时会在合适的等价类型之间进行向下转换,比如float64 to int64 if possible。
e.g:
data = {
'月份':['1月','2月','3月','4月','5月'],
'房租':[2000,2000,2000,2000,2000],
'水电':[300,280,None,310,290],
'餐费':[500,None,480,600,560],
'交通':[150,140,150,None,None]
}
df6 = pd.DataFrame(data)
print(df6.fillna(value='a')) #NAN填充为a
print(df6.fillna(method='ffill')) #前一行的值填充当前的NAN
去重
df6.drop_duplicates() #每行重复数据去重
df6.duplicated() #查询是否有重复,返回布尔值
替换
sales_data['sale_date'].replace('2024-10-1','2024-11-11') #按照索引替换
处理单元格内部数据 str
# 把name 全部变成大写
df6['name'].str.upper()
# 把name 首字母变成大写
df6['name'].str.capitalize()
# 索引使用
df6['name'].str[0]