Pandas处理分析数据常用语句

Pandas处理分析数据常用语句

本文包括了一些常用的数据清洗和处理方法的常用语句,涉及到一些Python基础的内容,比如:基本数据类型、数据类型转换、推导式、函数、lambda、数据结构、正则表达式等,如果需要,可以参考Python3 基础语法 | 菜鸟教程 (runoob.com)的基础部分。

import numpy as np
import pandas as pd
1、导入导出
#数据导入
df = df.read_csv('data.csv', sep=',')
'''
其他常用参数:
- `header`: 指定哪一行作为列名。默认情况下,Pandas 会将第一行作为列名,如果没有列名,则可以将 `header=None`。
- `index_col`: 指定哪一列作为行索引。
- `usecols`: 指定需要读取的列。可以传入列名或列索引。
- `dtype`: 指定每一列的数据类型。
- `skiprows`: 跳过文件的前几行。
- `nrows`: 读取文件的前几行。
'''


df = pd.read_json('E:\\data.json',lines = True)
#当设置为 True 时,函数会将每一行作为一个 JSON 对象进行解析,并返回一个包含这些对象的列表。这在处理大型 JSON 文件时非常有用,因为它允许你逐行读取文件,而不是一次性加载整个文件到内存中。



#.tsv 文件是一种文本文件,其数据以制表符(Tab)分隔的格式进行存储
df = pd.read_csv('data.tsv',sep = '\t')



#如果不确定文件中每列之间使用的具体空白字符是什么,可以使用 sep='\s+' 来读取文件
df = pd.read_table('data.data', sep='\s+', na_values='NaN')





#数据导出
df.to_csv('E:\\cleaned_data.csv',index=False)
2、查看行列数量
#查看dataframe的行数
df_row_num = df.shape[0]#包括空行

df_row_num = len(df)#包括空行



#查看dataframe的列数
df_column_num = df.shape[1]

df_column_num = len(df.columns)



#查看dataframe的前10行
print(df.head(10))



#dataframe中某一列非空行的总数
column2_num = df['column2'].notnull().sum()



#查看某一列有哪些元素
unique_column = df['column'].unique()


#查看某列去重后的元素个数
unique_column_num = df['column'].numique()
3、判断修改元素类型
#判断每列元素的类型(这里只包括bool、object、float、int,所以,想知道list、str之类的用下面的方法)
print(df.dtypes)


#判断某列里的元素的类型
element = df['Km'].iloc[0]
print("元素类型:", type(element))


#元素类型转换
df['column3'] = df['column3'].astype(float)
4、缺失值处理
#查看每列是否有缺失值并统计每列的空值个数
nan_nums = df.isnull().sum()
print(nan_nums)
#df.isnull()返回True/False直接说明是否有空值

#统计缺失值的总数
prin(nan_nums.sum())




#缺失值处理(根据实际情况选择,看数据本身之间的关联性和业务需求以及空值所在的列,有的时候空值所在的行不用删,也不用补,在分析某列数据的时候,再把这一列中的空值处理掉)
# 删除包含缺失值的行(注意dropna默认删除的是nan)
df.dropna(axis=0, inplace=True)

# 删除包含缺失值的列(一般不会删除列)
df.dropna(axis=1, inplace=True)

# 使用指定值填充所有缺失值
df.fillna(0, inplace=True)

# 使用每一列的平均值填充缺失值
df.fillna(df.mean(), inplace=True)
5、重复行处理
#查看df是否有重复行
duplicate_rows = df.duplicated().any()
print(duplicate_rows)
#返回True/False
#查看df的某一列是否有重复值。如果报错比较不了,记得转一下格式,例如:
products_categories['category'] = products_categories['category'].astype(str)
print(products_categories.duplicated().any())



#删除重复行
df.drop_duplicates(inplace = True) #inplace = True动原表
6、异常值处理
#判断是否有异常值
new_column3 = (df['column3']<0).any()
#.any() 返回一个布尔值,指示是否存在至少一个 True 值。
print(new_column3) #返回True/False

print((df['column3']>df['column4']).any())



#删除异常值所在的行
df.drop(df[df['column3']<0].index, inplace = True)

#保留正常值
df = df[df['column3'] >= 0]

#布尔索引取反
df = df[~(df['column3']>df['column4'])]
7、合并表
merge_pd = pd.merge(df1, df2, on = 'column1', how = 'left')
#left/right/inner/outer 这里和SQL用法一致
8、提取所需的列,组成一个新dataframe
#原dataframe:df。需要的列:column1,column2
column1 = df['column1']
column2 = df['column2']
new_df = pd.concat([column1,column2],axis = 1) #axis = 1沿着行的方向合并
new_df.columns = ['column1','column2']
#注:以上四句话虽然等效于new_df = new_df[['column1','column2']]这一句话,但是,上面那种方法,column1和column2可以来自于不同的dataframe,而且column1和column2可以是dataframe,不一定是series。可以设置axis=1, join='outer'等,按照行索引对齐,外连接等。

#删除空值,根据需求决定是否需要删
new_df.dropna(inplace = True)#inplace = True,覆盖原dataframe
print(new_df)



#前提:column1中元素出现次数的前100的元素。需要的列:column1,column2
column1 = df['column1'].value_counts()
column1_sorted = column1.sort_values(ascending = False)
top_100_column1 = column1.head(100).index.tolist()
new_df = df[df['column1'].isin(top_100_column1)]
new_df = new_df[['column1','column2']]
9、字典的应用
#输入column1列中的元素值,可以得到该元素对应的所有column2的值
#这里假设column2是字符串
df_dic = {}
for index,row in new_df.iterrows(): #iterrows用于迭代DataFrame中的每一行。index是行索引,row为该行的数据
    column1 = row['column1']
    column2 = row['column2']
    if column1 in df_dic:
        df_dic[column1].appened(column2)
    else:
        df_dic[column1] = [column2]#将符合条件的column2的值一列表的形式保存,默认,分隔
#如果想进一步处理column2的存储形式        
for column1,column2s in df_dic.items(): #items()迭代Series中的每个键值对
    formatted_column2s = '\n\n'.join([column2+'\n\n'+'-'*50  for column2 in column2s])
    #这里字符串之间用\n\n隔开,同时将每个字符串通过推导式变成字符串本身+\n\n+50个-
    df_dic[column1] = formatted_column2s
    
print(df_dic['column1列中的某一个元素']) #返回对应的column2的值   



#假设column2列中的字符串为"'as','zx','qw'"这种类型,统计columns列中as、zx、qw这类元素出现的次数
num_dic = {}
for index,row in new_df.iterrows():
    column2 = row['column2']
    for i in column2:
        i = i.strip().strip('"').strip("'")#去字符串首尾空格和引号
        if i in num_dic:
            num_dic[i] += 1
        else:
            num_dic[i] = i
#如果想获得元素出现次数最多的元素名
most_element = max(num_dic, key=num_dic.get)
most_element_count = num_dic[most_element]#出现次数

#通过字典求所有元素出现的次数总和
total = sum(num_dic.values())
10、转置
#行列转置.T
df3 = df.T




#复杂的转置.pivot_table
#这里举个例子:
'''
    categories   format values   total   percent_values  
0   Category A  values1     20      60        33.333333  
1   Category A  values2     25      60        41.666667  
2   Category A  values3     15      60        25.000000 
3   Category B  values1     35      96        36.458333 
4   Category B  values2     32      96        33.333333
5   Category B  values3     29      96        30.208333
6   Category C  values1     30      92        32.608696
7   Category C  values2     34      92        36.956522
8   Category C  values3     28      92        30.434783
9   Category D  values1     15      62        24.193548
10  Category D  values2     19      62        30.645161
11  Category D  values3     28      62        45.161290

这个dataframe怎么转换成下面的dataframe

   categories         values1         values2         values3    
0  Category A       33.333333       41.666667       25.000000            
1  Category B       36.458333       33.333333       30.208333               
2  Category C       32.608696       36.956522       30.434783              
3  Category D       24.193548       30.645161       45.161290            


'''
#这里先解释一下total列和percentage列
df['total'] = df.groupby('categories')['values'].transform('sum')
df['percent_values'] = df['values'] / df['total'] * 100

#转换操作
# 使用 pivot_table 将相同类别的数据合并到同一行中
result = df.pivot_table(index='categories', columns='format', values='percent_values').reset_index()
result.columns.name = None
result.reset_index(inplace=True)#原索引会变成一个名为 'index' 的列.
#参数drop=True会删除当前的行索引,并将整数索引设置为默认的行索引。
result.rename(columns={'index':'categories'},inplace=True)#这个列的名字会被改成 'categories'。这样,原来的索引就变成了一个普通的列,并且被重命名为 'categories'。
11、字符串处理
#处理字符串经常用到的几种方法:
#去除字符串的特殊字符.str.strip()
#字符串替换.str.replace()
#字符串提取.str.extract()
#字符串查找.str.contains()
#字符串分隔符.str.split()
#使用列表推导式和条件语句来过滤出非异常字符串




#字符串替换:
#将column3列中字符串长度超过10或者为''的转换为空值,并将有效字符串开头的特殊字符$删除以及删除字符串中间的',',最后将其转换为浮点数
df.loc[df['column3'].str.len()>10,'column3'] == np.nan
df['column3'] = df['column3'].replace('',np.nan)#replace后面也可以使用字典的形式,比如:.replace({'': np.nan})
df['column3'] = df['column3'].str.strip('$')
df['column3'] = df['column3'].str.replace(',','')
df['column3'] = df['column3'].astype(float)




#字符串查找、替换、提取
filtered_column7 = df[df['column7'].str.contains(r'(.*(CDs).*)', na=False)]
#str.contains()是 Pandas Series 对象的一个方法,用于检查 Series 中的每个元素是否包含指定的子字符串或正则表达式模式。
#na=False: 这个参数指定了在 Series 中是否将缺失值视为 False。如果设置为 False,则包含缺失值的元素会被视为不包含指定的子字符串。

#提取出数字部分
filtered_column7['column7'] = filtered_column7['column7'].str.replace(',','').str.extract(r'(\d*)').astype(int)
'''
r 前缀表示这是一个原始字符串,其中的反斜杠不会被转义,而是被当做普通字符对待。
\d+:表示匹配一个或多个数字。
\.?:表示匹配零个或一个小数点。\. 中的 \ 是转义字符,用于匹配实际的小数点而不是正则表达式中的特殊字符。
\d*:表示匹配零个或多个数字。

其他常用的:
\s:匹配任何空白字符,包括空格、制表符、换页符等等。等价于 [ \f\n\r\t\v]。
\w:匹配包括下划线的任何单词字符。等价于'[A-Za-z0-9_]'。
.:匹配除 "\n" 之外的任何单个字符。要匹配包括 '\n' 在内的任何字符,请使用象 '[.\n]' 的模式。
$:匹配输入字符串的结束位置。
'''

#删除重复值
iltered_column7.drop_duplicates(inplace = True)





#字符串分隔符
df['column11'] = df['column11'].str.strip('[]').str.split(',').apply(lambda x: [i.strip('[]') for i in x])
'''
strip 去除字符串首尾的指定字符
split(', ') 是字符串的一个方法,用于根据指定的分隔符将字符串拆分成多个子字符串,并返回一个包含这些子字符串的列表。
apply(lambda x: [i.strip('[]') for i in x]) 去除字符串中间的[]
'''
12、分箱
#先设置一个分箱边界。分箱边界可以是一个整数(表示分成几个等宽的箱子)或一个列表/数组(表示每个箱子的边界值)
#这里用数组
min_column3 = df['column3'].min()
max_column3 = df['column3'].max()
column3_range = np.arange(min_column3,max_column3+2)
df['column3'] = pd.cut(df['column3'], bins = column3_range)#默认左开右闭
13、统计某列的元素出现频率
column4_num = df['column4'].value_counts()
#返回的是一个Series,这个Series 的索引是 'column4' 列中的唯一值,而每个索引位置对应的值是该唯一值在 'column4' 列中出现的次数。


#如果想获取这个索引中索引次数最多的column4元素
column4_num_max = column4_num.idmax()
#除此以外, idxmin() 是 Pandas Series 对象的一个方法,用于返回具有最小值的元素的索引位置(如果有多个最小值,则返回第一个最小值的索引)。
14、排序
#按值降序
sorted_column5 = df.groupby('column1')['column5'].count().sort_values(ascending = False)


#按索引正序
sorted_column51 = df.groupby('column1')['column5'].count().sort_index(ascending = False)


#根据某一列排序
sorted_df = df.sort_values(by = 'column6', axis = 0, inplace = False)#默认axis = 0,按行排序。默认inplace=False,不覆盖原dataframe
15、聚合
#.transform() 方法会在原 DataFrame 中按需增加列,不是创建一个新的series
#举个例子
df['column8'] = df.groupby('column1')['column8'].transform('mean')
#这里如果写.mean()会生成一个新的 Series返回一个包含每个分组的均值的 Series,其索引是分组的键column1。
#所以聚合的时候按照需求选择方法




#两个聚合条件
column1_3_count = df.groupby(['column1','column3']).size().unstack(fill_value=0).stack().reset_index(name='count')
print(column1_3_count)
#.size() 返回的是每个分组中的元素数量,包括 NaN 值。
#.count() 返回的是每个分组中非 NaN 值的数量。
#.unstack(fill_value=0):这一步是将分组后的结果进行透视,将 'column3' 列的唯一值转换为列索引,形成一个透视表。fill_value=0 表示如果某个组合不存在,count用0填充。
#.stack():这一步是将透视表重新堆叠为原始格式,使得 DataFrame 中的每一行都对应一个 'column1' 和 'column2' 组合。
#.reset_index(name='count'):.reset_index() 方法会将现有的索引重置为默认的整数索引(0, 1, 2, ...),并将重置后的索引作为新的列添加到 DataFrame 中。name='count' 参数用于指定新添加的列的名称为 'count'。

16、.apply()

将 DataFrame 或 Series 中的每个元素都应用括号里的函数进行求值

#例1:使用已有函数
#假设column9元素为字符串'['a','b','c']'
df['column9'] = df['column9'].apply(eval)
#eval() 函数会尝试将传递给它的字符串参数解析为 Python 表达式,并尝试对其进行求值。它会根据字符串中的内容来尝试识别元素的正确格式,并进行相应的解析。
#所以这个解析完,会变成列表['a','b','c']




#例2:使用lambda函数
#假设column9元素为列表['a','b','c'
df['column9'] = df['column9'].apply(lambda x:x[1])#保留列表中索引为1的元素

#假设column10元素为整数,例如2,如果想把其改成两位整数,例如02
df['column10'].apply(lambda x: '{:02d}'.format(x)).astype(int)
'''
其中 {} 是格式化字符串中的占位符,02 表示至少两位数,并且不足两位时在前面补零,d 表示数值类型。

三位整数'{:03d}'.format(x)
小数点后三位的百分数'{:.3f}%'.format(x * 100)
'''




#例3:使用自定义函数
#假设column9元素为字典{'Format:': 'abcd'}
def extract_format(column9):
    if isinstance(column9,dict):#isinstance() 用于检查一个对象是否是某个特定类型或特定类型的子类的实例。
        return column9.get('Format:', None)#从字典 column9 中获取键为 'Format:' 的值,如果字典中不存在这个键,则返回 None。
    else:
        return None
df['format'] = df['column9'].apply(extract_format)
17、日期处理
#将日期时间转换成datetime格式
df['Time'] = pd.to_datetime(df['Time'], format='%m %d, %Y')#format后面写的就是原来的日期格式
 
    
    
#只保留年月日,不保留时分秒
df['Time'] = df['Time'].dt.date



#将df所有日期的年份大于2000年的减100年
df.loc[df['Time'].dt.year > 2000, 'Time'] -= pd.offsets.DateOffset(years=100)



#将单独的年月日列组合起来
date_str = df['Yr'].astype(str) + '-' + df['Mo'].astype(str) + '-' + df['Dy'].astype(str)#先组成字符串

df['Date'] = pd.to_datetime(date_str)




#将日期列设为索引
df.set_index('Date', inplace=True)
18、.agg()
#同时求多列的每列最小值,最大值,平均值和标准差
column_stats = df.agg({
    'column12': ['min', 'max', 'mean', 'std'],
    'column13': ['min', 'max', 'mean', 'std'],
    'column14': ['min', 'max', 'mean', 'std'],
    'column15': ['min', 'max', 'mean', 'std'],
    'column16': ['min', 'max', 'mean', 'std'],
    'column17': ['min', 'max', 'mean', 'std']
})
print(column_stats)


#计算多列的每行的最小值,最大值,平均值和标准差
row_stats = df.loc[:,'column12':'column17'].agg(['min','max','mean','std'],axis = 1)
print(row_stats)
19、重采样
# 将索引转换为日期时间类型
df.index = pd.to_datetime(df.index)

#对于数据,分别以年为频率取样
print(df.index.dtype)
resampled_yearly = df.iloc[:,3:].resample('Y').mean()
print(resampled_yearly)


#对于数据,分别以月为频率取样
resampled_monthly = df.iloc[:,3:].resample('M').mean()
print(resampled_monthly)
20、.where()
import pandas as pd

# 创建示例 DataFrame
df = pd.DataFrame({'A': [1, 2, 3, 4, 5],
                   'B': [6, 7, 8, 9, 10]})

# 使用 where 方法将不符合条件的值替换成 NaN
result = df.where(df['A'] > 3, other = np.nan, inplace = False)
'''
DataFrame.where(cond, other=np.nan, inplace=False, axis=None, level=None, errors='raise', try_cast=False)
- `cond`:条件,可以是一个布尔数组、布尔表达式或者一个可调用对象,用于指定过滤条件。
- `other`:要替换不符合条件的值,默认为 NaN。
- `inplace`:是否在原地修改 DataFrame,即是否覆盖原来的数据,默认为 False。
- `axis`:指定操作的轴,默认为 None,表示在所有轴上应用。
- `level`:指定在具有多层索引的 DataFrame 中操作的级别。

- `axis=0` 表示沿着行的方向进行操作,即在行上应用操作。
- `axis=1` 表示沿着列的方向进行操作,即在列上应用操作。
'''

print(result)
'''
结果:
     A     B
0  NaN   NaN
1  NaN   NaN
2  NaN   NaN
3  4.0   9.0
4  5.0  10.0
'''
  • 2
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值