Pandas数据处理技巧

  • Post author:
  • Post category:其他


一、数据存取

1、读取

------Csv------
pd.read_csv('pwd')

------Excel------
pd.read_excel('pwd')
# 读取分表
pd.read_excel('pwd',sheet_name=0/'')
# 导入指定列
pd.read_excel('pwd',usecols='A:C,E')
pd.read_excel('pwd',usecols=[1,2,3,5])
# 指定表头
pd.read_excel('pwd',header=1)

--------txt------
file_path = '../files/access_pvuv.txt'
pd.read_csv(file_path, sep='\t', header=None, names=['pdate', 'pv', 'uv'])
"""
sep: 指定列的分隔符
header: 没有标题行设置为None
names: 自定义列名
"""

------my sql------
import pymysql
import pandas as pd

# 创建数据库连接
conn = pymysql.connect(host='0.0.0.0', user='***', password='***', database='demo', charset='utf8')

# 使用pd.read_sql读取数据
pd.read_sql("select * from table_name", con=conn)

---------json----------
pd.read_json()
or
import json
f = open('')
t = json.load(f)
data=pd.DataFrame(t)

2、存储

 data.to_excel('pwd',index=True/False) # 是否使用索引
 data.to_csv('pwd')

3、分sheet存储

with pd.ExcelWriter('文件路径') as writer:
  data.to_excel(writer, sheet_name='分sheet名字')

二、数据处理

1、基本信息

# 数据前几行
data.head()
# 数据基本信息
data.info()
# 描述性统计
data.describe()
# 按照索引排序
data.sort_index(ascending=True,inplace=False) #升序排列,作用于原对象
# 按照值排序
data.sort_values(by='',ascending=True)
# 删除列
del dat['']

2、分列

data=data.str.split('分列依据符号',expand=True)

3、替换

data.replace(to_replace=None, value=None, inplace=False, limit=None, regex=False, method='pad')

条件替换:

'''
to_replace:被替换的值
value:替换后的值
inplace:是否要改变原数据,False是不改变,True是改变,默认是False
limit:控制填充次数
regex:是否使用正则,False是不使用,True是使用,默认是False
method:填充方式,pad,ffill,bfill分别是向前、向前、向后填充
'''
条件替换
df.loc[<mask>(here mask is generating the labels to index) , <optional column(s)> ]
例子:
df.loc[df['First Season'] > 1990, 'First Season'] = 1

4、格式转换

# 显示格式
data.dtypes
# 格式转换
data=data.astype('int')

data[''].apply(lambda x:format(x,'.2%')) # 百分比保留两位小数
data[''].apply(lambda x:format(x,'.2f')) # 小数点后保留两位

data.round(2)

# 日期格式
import datetime
datetime.datetime.now().strftime("%Y-%m-%d %H:%M:%S")
datetime.date(2022,2,1).strftime("%Y-%m-%d")
# 时间戳转化为日期
datetime.fromtimestamp(time.time())

# 格式判断
isinstance(x,datetime.datetime)

5、去重

# 判断是否有重复值
data.duplicated().value_counts()
# 删除重复值
data.drop_duplicates(subset=[],keep='',inplace=True/False)
# subset:以哪几列为基准,默认为所有列
# keep:保留重复出现的那一个值,first:第一个出现的;last:最后一个出现的;False:一个都不保留;
# inplace:是否替换原始数据

6、缺失值处理

# 判断是否有缺失值
data.isnull()
# 判断每一列是否有缺失值
data.isnull().any()
# 删除缺失值
data.dropna(axis,subset,how,thresh,inplace)
'''
axis: 删除行还是列,行是0或index,列是1或column,默认是行
subst: 删除某几列的缺失值,可选,默认为所有列
how: any or all,any表明只要出现1个就删除,all表示所有列均为na才删
thresh: 缺失值的数量标准,达到这个阈值才会删除
inplace: 是否替换
'''
# 缺失值填充
data.fillna(value,method,{},limit,inplace,axis)
# 单独一列填充,可以用inplace=teueti替换原值
# 多列填充直接重新赋变量
'''
value: 可以传入一个字符串或数字替代Na,值可以是指定的或者平均值,众数或中位数等
method: 有ffill(用前一个填充)和bfill(用后一个填充)两种
{}: 可以根据不同的列填充不同的值,列为键,填充值为值
limit: 限定填充的数量
inplace: 是否直接在原文件修改
axis: 填充的方向,默认是0,按行填充
'''

7、异常值处理

# 异常值查找
1、范围查找
datamean=data[].mean()
datastd=data.std()
topnuml=datamean+2*datastd
bottomnuml=datamean-2*datastd
any(data)>topnuml
any(data)<bottomnuml
2、借助分布查找
2.1 借助散点图
from matplotlib import pyplot as plt
plt.scatter(data1, data2)
plt.show()
2.2 借助箱形图
plt.boxplot(data)
# 异常值修改(利用均值和方法)
a = data[].mean()+data[].std()*4
b = data[].mean()-data[].std()*4
c = data[]
c[(c>=a)|(c<=b)]=np.nan
c.fillna(c.median(),inplace=True)
# 异常值修改(利用分位数)
a = data[].quantile(0.75)
b = data[].quantile(0.25)
c = data[]
c[(c>=(a-b)*1.5+a)|(c<=b-(a-b)*1.5)]=np.nan
c.fillna(c.median(),inplace=True)

8、修改行列名

# 修改列名
data.rename(columns={'':''},inplace=True)
# 修改行名
data.rename({'':''},inplace=True)
# 重置索引
data.reset_index(inplace=True,drop=True) # 丢掉原有索引
# 设置其他列为索引
data.set_index('id_new')

9、数据筛选

data.where(data.列+条件)
data.isin([]) #
data[data['列']判断条件]
data[data['列'].isnull()]
data[data['列'].notnull()]
# 字符筛选
data.loc[data[''].str.contains('')]
data.loc[~data[''].str.contains('')] # 不包含


# Pandasdatetime64[ns]不能直接与datetime.date相比,需要用pd.Timestamp进行转化
data['日期']=data["日期"].values.astype('datetime64')  #如果已为日期格式则此步骤可省略
import datetime
s_date = datetime.datetime.strptime('2020-04-30', '%Y-%m-%d').date()  #起始日期
e_date = datetime.datetime.strptime('2020-06-01', '%Y-%m-%d').date()  #结束日期

data[(data.日期>pd.Timestamp(s_date))&(data.日期<pd.Timestamp(e_date))]
# 数据清洗
# 筛选整数:新增一列,适用.is_integer()判断一个元素是否为整数
df.apply(lambda x:x.is_integer,axis=1)

# 筛选数值类:使用函数.isdigit() 判断是否为数值
df.str.isdigit().isnull.dropnaa()

# 筛选日期类:使用函数to_datetime(),将非日期类替换为NaN
df['']=pd.to_datetime(df[''],errors=coerce)

# 筛选非字符类,使用isinstance函数判断
df[~df[''].apply(lambda x: isinstance(x,str))]

10、删除行列

data.drop(columns=[''],inplace=True)
data.drop(index=[''],inplace=True)

11、新增行

series=pd.Series({'name1':value1,'name2':value2,) #name 就是index的值
df.append(series)

df.loc['']={'':,'':}

12、apply函数

# dataframe
df.apply(func,axis=0)	#添加行,按列计算
# 示例:
df.apply(np.mean)	#按列求平均值
data.loc['汇总'] = data.apply(lambda x: x.sum())	# 按列求和,添加汇总行

df.apply(func,axis=1) #添加列,按行计算
# 示例
df['C']=df.apply(lambda x:x['A']+x['B'],axis=1) # 添加C列,为A列+B列
data['汇总'] = data.apply(lambda x: x.sum(), axis=1)	# 按行求和,添加汇总列

# Series
se.apply(lambda x:x if instance(x,(int,float)) else 0) #格式处理:非int、float类替换为0

13、pandas遍历

# 按行遍历
for index,row in df.iterrows():
  print(index,row['name'])

三、数据透视

1、分组聚合

data.groupby(['','']).count()/mean()...
分组排序:df.groupby('name').apply(lambda x: x.sort_values('score', ascending=False))

2、类开窗函数

'''
分组聚合后排序,组内增加序号
'''
# df.columns: name	class(组)	score(排序依赖值)

# 1、先按照组降序排列
df=df.groupby('class',sort=False).apply(lambda x:x.sort_values('score',
                                                                ascending=False)).reset_index(drop=True)
# 在组内增加排序列
df['rank']=None
# 标识初始组名
flag=df.loc[0].values[1]
# 设置初始序号
rank=0
# 根据df长度遍历
for i in range(len(df)):
  # 判断组名是否与初始组名一致
  temp=df.loc[i].values[1]
  # 同一分组
  if temp==flag:
    rank+=1
   else:
    # 更新组名
    flag=temp
    # 重新排序,设置初始序号为1
    rank=1
   df.loc[i]['rank']=rank
df

3、行列转换

# 透视表行列转换
data = pd.pivot_table(data, index=[''], columns='', values='')
# 非透视表行列转换
# 二级索引变列
data.set_index(['',''])
data.unstack()

4、添加汇总行

data.loc['汇总'] = data.apply(lambda x: x.sum())

5、添加汇总列

data['汇总'] = data.apply(lambda x: x.sum(), axis=1)

6、分箱

# list中为分割的点
list=[]
pd.cut(data,list)
---------
pd.cut(data.列,bins=,labels=[])
# bins:指定区间数量or区间间断点
# labels:设置区间标签
# eg: pd.cut(data.salary,bins = [0,10,20,30,40,50],labels = ['低','中下','中','中上','高'])
---------
# 分位数区间划分
pd.qcut(data,q=,labels=)

四、数据联合

1、数据拼接

# 数据拼接
pd.concat([data1,data2],axis=0/1,ignore_index=True/False)
# axis:横向or纵向拼接,默认为纵向
# ignore_index:是否保留原索引

2、数据联合

pd.merge(left, right, how='inner', on=None, left_on=None, right_on=None,
         left_index=False, right_index=False, sort=True,
         suffixes=('_x', '_y'), copy=True, indicator=False,
         validate=None)
# 示例: data = pd.merge(data1, data2, how='left',left_index=True, right_index=True)

'''
on: 要加入的列或索引级别名称
left_on:左侧DataFrame中的列或索引级别用作键
right_on: 右侧DataFrame中的列或索引级别用作键
left_index: 如果为True,则使用左侧DataFrame中的索引(行标签)作为其连接键。 对于具有MultiIndex(分层)的DataFrame,级别数必须与右侧DataFrame中的连接键数相匹配。
right_index: 与left_index功能相似。
how: One of ‘left’, ‘right’, ‘outer’, ‘inner’
sort: 按字典顺序通过连接键对结果DataFrame进行排序。 默认为True,设置为False将在很多情况下显着提高性能。
suffixes: 用于重叠列的字符串后缀元组。 默认为(‘x’,’ y’)。
copy: 始终从传递的DataFrame对象复制数据(默认为True),即使不需要重建索引也是如此。
indicator:将一列添加到名为_merge的输出DataFrame,其中包含有关每行源的信息。 _merge是分类类型,并且对于其合并键仅出现在“左”DataFrame中的观察值,取得值为left_only,对于其合并键仅出现在“右”DataFrame中的观察值为right_only,并且如果在两者中都找到观察点的合并键,则为left_only。
'''



版权声明:本文为Ruiruiaichirou原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。