pandas基础上

目录

1.读文件

2.Pandas数据结构

3.pd查询

1)使用单个列表值查询数据

2).使用值列表批量查询

3).使用数值区间进行范围查询

4).使用条件表达式查询

5).调用函数查询

4.pandas 增加修改列

1)直接赋值

2)apply方法

3)df.assign方法

4)按条件选择分组分别赋值

5.pandas统计

6.pandas 缺省值

7.pandas排序

8.pandas字符串处理

9.pandas axis

10.pandas index

11.pandas merge

12.pandas实现数据合并

13.pandas EXCEL拆分合并


1.读文件

读取CSV、txt、 都是用 read_csv ,excel :read_excel,读数据库可以用 pd.read_sql函数

import pandas as pd 
fpath = "D:/test/1.csv"
df = pd.read_csv(fpath, encoding = 'gb18030')
df.head()
#查看行数,列数
df.shape
df.columns
#查看索引列
df.index
df.dtypes

 

2.Pandas数据结构

Series是一种类似于一维数组的对象,它由一组数据(不同数据类型)以及一组与之相关的数据标签(即标签)组成。

import pandas as pd
import numpy as np
myS = pd.Series([1,'a',5.2,7])
#myS = pd.Series([1,'a',5.2,7],index=['a','b','c','d'])
#myS =pd.Series(dict)
myS
myS.index
myS.values

 

DataFrame查询一行返回的是series,多行是dataframe结构

import pandas as pd
import numpy as np
data = {'my1':['a','b',1],
		'my2':['d','e',1],
		'my3':['c',1.5,2]}
df = pd.DataFrame(data)
df.dtypes
df.columns
df.index
#查询多列
df[['my1','my2']]
#查询一行,返回index=1的行
df.loc[1]
df.loc[1:2]

 

3.pd查询

pandas查询数据的集中方法:
1.df.loc方法,根据行列标签值查询
2.df.iloc方法,根据行列数字位置查询
3.df.where方法
4.df.query方法

.loc既能查询,又能覆盖写入,强烈推荐,

a.准备数据:

import pandas as pd
df = pd.read_csv("./pandas/ant-learn-pandas/datas/beijing_tianqi/beijing_tianqi_2018.csv", engine='python',
                 encoding='utf-8')

# 设定索引日期,方便日期筛选
df.set_index('ymd', inplace=True)

# 替换掉温度后缀℃
df.loc[:, 'bWendu'] = df["bWendu"].str.replace("℃", "").astype('int32')
df.loc[:, 'yWendu'] = df["yWendu"].str.replace("℃", "").astype('int32')

1)使用单个列表值查询数据

# 得到单个值(2018-01-03最高温度)
res = df.loc["2018-01-03", "bWendu"]
print(res)

# 得到一个Series(2018-01-03最高温度和最低温度)
ret = df.loc["2018-01-03", ["bWendu", "yWendu"]]
print(ret)

2).使用值列表批量查询

# 得到Series
s1 = df.loc[['2018-01-03', '2018-01-04', '2018-01-05'], 'bWendu']
print(s1)

# 得到DataFrame
s2 = df.loc[['2018-01-03', '2018-01-04', '2018-01-05'], ['bWendu', 'yWendu']]

3).使用数值区间进行范围查询

# 行index按区间
s3 = df.loc['2018-01-03':'2018-01-05', 'bWendu']
print(s3)

# 列index按区间
s4 = df.loc['2018-01-03', 'bWendu':'fengxiang']
print(s4)

# 行和列都按区间查询
s5 = df.loc['2018-01-03':'2018-01-05', 'bWendu':'fengxiang']
print(s5)

4).使用条件表达式查询

# 简单条件查询,最低温度低于-10度的列表
s6 = df.loc[df["yWendu"] < -10, :]
print(s6)

# 复杂条件查询,查一下我心中的完美天气
# 查询最高温度小于30度,并且最低温度大于15度,并且是晴天,并且天气为优的数据
s7 = df.loc[(df["bWendu"] <= 30) & (df["yWendu"] >= 15) & (df["tianqi"] == '晴') & (df["aqiLevel"] == 1), :]
print(s7)

5).调用函数查询

# 直接写lambda表达式
s8 = df.loc[lambda df: (df["bWendu"] <= 30) & (df["yWendu"] >= 15), :]
print(s8)

# 编写自己的函数,查询9月份,空气质量好的数据
def query_my_data(df):
    return df.index.str.startswith("2018-09") & (df["aqiLevel"] == 1)

s9 = df.loc[query_my_data, :]
print(s9)

4.pandas 增加修改列

1)直接赋值

# 注意,df["bWendu"]其实是一个Series,后面的减法返回的是Series 
df.loc[:, "wencha"] = df["bWendu"] - df["yWendu"]

2)apply方法

Apply a function along an axis of the DataFrame.

Objects passed to the function are Series objects whose index is either the DataFrame’s index (axis=0) or the DataFrame’s columns (axis=1).

实例:添加一列温度类型:

  1. 如果最高温度大于33度就是高温
  2. 低于-10度是低温
  3. 否则是常温
def get_wendu_type(x):
    if x["bWendu"] > 33:
        return '高温'
    if x["yWendu"] < -10:
        return '低温'
    return '常温'

# 注意需要设置axis==1,这是series的index是columns
df.loc[:, "wendu_type"] = df.apply(get_wendu_type, axis=1)

# 查看温度类型的计数
df["wendu_type"].value_counts()

3)df.assign方法

Assign new columns to a DataFrame.

Returns a new object with all original columns in addition to new ones.

# 可以同时添加多个新的列
df.assign(
    yWendu_huashi = lambda x : x["yWendu"] * 9 / 5 + 32,
    # 摄氏度转华氏度
    bWendu_huashi = lambda x : x["bWendu"] * 9 / 5 + 32
)

4)按条件选择分组分别赋值

# 先创建空列(这是第一种创建新列的方法)
df['wencha_type'] = ''

df.loc[df["bWendu"]-df["yWendu"]>10, "wencha_type"] = "温差大"

df.loc[df["bWendu"]-df["yWendu"]<=10, "wencha_type"] = "温差正常"

 

5.pandas统计

df.describe()	# 提取所有数字列统计结果
df["bWendu"].mean()	# 查看单个Series的平均数据(bWendu)
df["bWendu"].max()	# 最高温
df["bWendu"].min()	# 最低温
df["fengxiang"].unique()	#进行去重的输出结果。
df["fengxiang"].value_counts() # 统计"fengxiang"这个列标签中各种风向出现的次数。

#协方差:用于衡量两个变量的总体误差。衡量同向反向程度,如果协方差为正,说明X,Y同向变化,协方差越大说明同向程度越高;如果协方差为负,说明X,Y反向运动,协方差越小说明反向程度越高。
#相关系数:衡量相似度程度,当他们的相关系数为1时,说明两个变量变化时的正向相似度最大,当相关系数为-1时,说明两个变量变化的反向相似度最大
df.cov()	# 协方差矩阵
df.corr()	# 相关系数矩阵
df["aqi"].corr(df["bWendu"])	# 单独查看空气质量和最高温度的相关系数

6.pandas 缺省值

studf.isnull()
studf["分数"].isnull()
studf.loc[studf["分数"].notnull(), :]	# 筛选没有空分数的所有行
studf.dropna(axis="columns", how='all', inplace=True)	#删除都为空值所对应的列

#axis : 删除行还是列,{0 or ‘index’, 1 or ‘columns’}, default 0
#how :如果等于any则任何值为空都删除,如果等于all则所有值都为空才删除
#inplace : 如果为True则修改当前df,否则返回新的df


tudf.fillna({"分数":0})	#把分数这列为空值的地方填充为0
# 等同于
studf.loc[:, '分数'] = studf['分数'].fillna(0) #查询分数空值的覆盖写入

# 使用前面的有效值填充,用ffill:forward fill
studf.loc[:, '姓名'] = studf['姓名'].fillna(method="ffill")

to_excel()#写到excel中

7.pandas排序

#DataFrame.sort_values(by, ascending=True, inplace=False)
#参数说明:
#by:字符串或者List<字符串>,单列排序或者多列排序
#ascending:bool或者List,升序还是降序,如果是list对应by的多列 inplace:是否修改原始DataFrame

# 分别指定升序和降序
df.sort_values(by=["aqiLevel", "bWendu"], ascending=[True, False])

8.pandas字符串处理

Pandas的字符串处理
1).使用方法:先获取Series的str属性,然后在属性上调用函数;
2).只能在字符串列上使用,不能数字列上使用
3).Dataframe上没有str属性和处理方法
4).Series.str并不是Python原生字符串,而是自己的一套方法,不过大部分和原生str很相似

# 字符串替换函数
df["bWendu"].str.replace("℃", "")
# 判断是不是数字
df["bWendu"].str.isnumeric()
df["aqi"].str.len()
condition = df["ymd"].str.startswith("2018-03")
df[condition].head()

#怎样提取201803这样的数字月份?
#1、先将日期2018-03-31替换成20180331的形式
#2、提取月份字符串201803
df["ymd"].str.replace("-", "")
df["ymd"].str.replace("-", "").str.slice(0, 6)
# slice就是切片语法,可以直接用(同上操作)
df["ymd"].str.replace("-", "").str[0:6]



# 添加新列
def get_nianyueri(x):
    year,month,day = x["ymd"].split("-")
    return f"{year}年{month}月{day}日"
df["中文日期"] = df.apply(get_nianyueri, axis=1)


问题:怎样将“2018年12月31日”中的年、月、日三个中文字符去除?

# 方法1:链式replace
df["中文日期"].str.replace("年", "").str.replace("月","").str.replace("日", "")

#Series.str默认就开启了正则表达式模式

# 方法2:正则表达式替换
df["中文日期"].str.replace("[年月日]", "")

9.pandas axis

按哪个axis,就是这个axis要动起来(类似被for遍历),其它的axis保持不动

10.pandas index

更方便的数据查询;
使用index可以获得性能提升;
自动的数据对齐功能;
更多更强大的数据结构支持;

1.使用index查询数据

#如果index是唯一的,Pandas会使用哈希表优化,查询性能为O(1);
#如果index不是唯一的,但是有序,Pandas会使用二分查找算法,查询性能为O(logN);
#如果index是完全随机的,那么每次查询都要扫描全表,查询性能为O(N);


# drop==False,让索引列还保持在column
df.set_index("userId", inplace=True, drop=False)
df.index
# 使用index的查询方法
df.loc[500].head(5)
# 使用column的condition查询方法(同上)
df.loc[df["userId"] == 500].head()

#试验1:完全随机的顺序查询

# 将数据随机打散
from sklearn.utils import shuffle
df_shuffle = shuffle(df)
df_shuffle.head()
# 索引是否是递增的
df_shuffle.index.is_monotonic_increasing
# 索引是否是唯一的
df_shuffle.index.is_unique
# 计时,查询id==500数据性能
%timeit df_shuffle.loc[500]


#实验2:将index排序后的查询
df_sorted = df_shuffle.sort_index()
# 索引是否是递增的
df_sorted.index.is_monotonic_increasing
df_sorted.index.is_unique
%timeit df_sorted.loc[500]

11.pandas merge

1、merge的语法:
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)

left,right:要merge的dataframe或者有name的Series
how:join类型,‘left’, ‘right’, ‘outer’, ‘inner’
on:join的key,left和right都需要有这个key
left_on:left的df或者series的key
right_on:right的df或者seires的key
left_index,right_index:使用index而不是普通的column做join
suffixes:两个元素的后缀,如果列有重名,自动添加后缀,默认是(‘x’, ‘y’)

###############################例子######################
#内连接
pd.merge(df1, df2, on='sno')
pd.merge(df1, df2, how='inner')
pd.merge(df1, df2, how='left')
pd.merge(left, right, how='right')
pd.merge(left, right, how='outer')
pd.merge(left, right, on='key', suffixes=('_left', '_right'))#这里是以'_left', '_right'来区分

12.pandas实现数据合并

使用场景:
批量合并相同格式的Excel、给DataFrame添加行、给DataFrame添加列

一句话说明concat语法:

  • 使用某种合并方式(inner/outer)
  • 沿着某个轴向(axis=0/1)
  • 把多个Pandas对象(DataFrame/Series)合并成一个。

concat语法:pandas.concat(objs, axis=0, join=‘outer’, ignore_index=False)

  • objs:一个列表,内容可以是DataFrame或者Series,可以混合
  • axis:默认是0代表按行合并,如果等于1代表按列合并
  • join:合并的时候索引的对齐方式,默认是outer join,也可以是inner join
  • ignore_index:是否忽略掉原来的数据索引

append语法:DataFrame.append(other, ignore_index=False)

  • append只有按行合并,没有按列合并,相当于concat按行的简写形式
  • other:单个dataframe、series、dict,或者列表
  • ignore_index:是否忽略掉原来的数据索引
#1.默认的concat,参数为axis=0、join=outer、ignore_index=False
pd.concat([df1,df2])#行索引不能忽略
#2.使用ignore_index=True可以忽略原来的索引
pd.concat([df1,df2], ignore_index=True)#行索引忽略
#3.使用join=inner过滤掉不匹配的列
pd.concat([df1,df2], ignore_index=True, join="inner")
4.使用axis=1相当于添加新列
s2 = df1.apply(lambda x:x["A"]+"_GG", axis=1)
s2.name="G"
pd.concat([s1,s2], axis=1)
pd.concat([s1,df1,s2], axis=1)

 

DataFrame.append按行合并数据
df1 = pd.DataFrame([[1, 2], [3, 4]], columns=list('AB'))
df2 = pd.DataFrame([[5, 6], [7, 8]], columns=list('AB'))

一行一行的给DataFrame添加数据

# 一个空的df
df = pd.DataFrame(columns=['A'])

#低性能版本
for i in range(5):
    # 注意这里每次都在复制
    df = df.append({'A': i}, ignore_index=True)

# 高性能版本,第一个入参是一个列表,避免了多次复制
pd.concat(
    [pd.DataFrame([i], columns=['A']) for i in range(5)],
    ignore_index=True
)

13.pandas EXCEL拆分合并

#拆分:


#(1)计算拆分后的每个excel的行数
total_row_count = df_source.shape[0]
# 这个大excel,会拆分给这几个人
user_names = ["xiao_shuai", "xiao_wang", "xiao_ming", "xiao_lei", "xiao_bo", "xiao_hong"]
# 每个人的任务数目
split_size = total_row_count // len(user_names)
if total_row_count % len(user_names) != 0:
    split_size += 1

#(2)拆分成多个dataframe
df_subs = []
for idx, user_name in enumerate(user_names):
    # iloc的开始索引
    begin = idx*split_size
    # iloc的结束索引
    end = begin+split_size
    # 实现df按照iloc拆分
    df_sub = df_source.iloc[begin:end]
    # 将每个子df存入列表
    df_subs.append((idx, user_name, df_sub))

#(3)拆分成多个dataframe
for idx, user_name, df_sub in df_subs:
    file_name = f"{splits_dir}/crazyant_blog_articles_{idx}_{user_name}.xlsx"
    df_sub.to_excel(file_name, index=False)



#合并
(1)遍历文件夹,得到要合并的Excel文件列表
(2)分别读取到dataframe,给每个df添加一列用于标记来源
(3)使用pd.concat进行df批量合并
(4)将合并后的dataframe输出到excel

#1. 遍历文件夹,得到要合并的Excel名称列表
import os
excel_names = []
for excel_name in os.listdir(splits_dir):
    excel_names.append(excel_name)


#2分别读取到dataframe
df_list = []#用于存储各个读取出来的dataframe

for excel_name in excel_names:
    # 读取每个excel到df
    excel_path = f"{splits_dir}/{excel_name}"
    df_split = pd.read_excel(excel_path)
    # 得到username
    username = excel_name.replace("crazyant_blog_articles_", "").replace(".xlsx", "")[2:]
    print(excel_name, username)
    # 给每个df添加1列,即用户名字
    df_split["username"] = username
    df_list.append(df_split)

#使用pd.concat进行合并
df_merged = pd.concat(df_list)
df_merged.shape
df_merged.head()
df_merged["username"].value_counts()

df_merged.to_excel(f"{work_dir}/crazyant_blog_articles_merged.xlsx", index=False)
	

 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值