Pandas基础使用指南之排序、字符串日期处理和文件合并拆分技巧

作者:

文章目录
  • 对于字符串的处理,我们一般都使用str进行,而对于日期,我们用dt,直接通过底下的代码我们来看 df = pd.DataFrame({“姓名”:[“张三”,”李四”,”王五”,”赵六”,”王二”], “出生日期”:[“2000-01-01″,”2001-02-02″,”2002-03-03″,”2003-04-04″,”2004-05-05”], “分数”:[“90分”,”29分”,”78分”,”46分”,”57分”]}) print(df.dtypes) print(“=”*30) df[“出生日期”] = pd.to_datetime(df[“出生日期”]) # 转换为日期类型 print(df[“出生日期”].dtype) # datetime64[ns] # df[“出生日期”] = df[“出生日期”].str.replace(“1″,””) # 错误用法,str只能为字符串服务 df[“出生日期”] = df[“出生日期”].dt.strftime(“%Y-%m-%d”) # 转换为字符串类型 print(df[“出生日期”].dtype) # object df[“分数”] = df[“分数”].str.replace(“分”,””).astype(int) # 转换为整数类型 print(df) 输出如下,我们一个一个做分析,首先我们定义了一个DataFrame,可以发现初始都是字符串,因此输出为object,然后我们通过to_datetime将其改成了标准的日期格式,因此输出为datetime64[ns],同样我们也可以通过dt.strftime将其转换为字符串格式,对于字符串格式,我们可以使用str下的若干方法进行处理,上述演示中只是将“分”这个字删除,并转换为整型: 姓名      object出生日期    object分数      objectdtype: object==============================datetime64[ns]object   姓名        出生日期  分数0  张三  2000-01-01  901  李四  2001-02-02  292  王五  2002-03-03  783  赵六  2003-04-04  464  王二  2004-05-05  57 同时pandas严格约定str只服务于字符串,如果对其他格式使用,则会报错,对于字符串的处理,还有一个很强大的工具就是正则表达式,我们同样可以使用正则表达式进行处理,但是注意使用regex=True告诉程序这个是正则表达式: # 常规复杂的三步替换 df[“出生日期”] = df[“出生日期”].str.replace(“年”,””).str.replace(“月”,””).str.replace(“日”,””) # 正则表达式替换 df[“出生日期”] = df[“出生日期”].str.replace(“[年月日]”,””,regex=True)
  • 如果需要做DataFrame的连接,我们常常使用concat方法,其重要的三个参数分别是 axis=0 代表按行连接,否则是按列连接 ignore_index=True 表示重新生成一个新的索引,否则保留原始索引 join="outer" 表示保留所有非重复字段,join="inner"则表示只保留重合字段 df1 = pd.DataFrame({“A”:[1,2,3], “B”:[6,7,8]}) df2 = pd.DataFrame({“B”:[4,5,6], “F”:[9,10,11]}) print(pd.concat([df1,df2],axis=1)) print(pd.concat([df1,df2],axis=0,ignore_index=True,join=”outer”)) 输出结果为:    A  B  B   F0  1  6  4   91  2  7  5  102  3  8  6  11     A  B     F0  1.0  6   NaN1  2.0  7   NaN2  3.0  8   NaN3  NaN  4   9.04  NaN  5  10.05  NaN  6  11.0 在输出中,如果 ignore_index=False ,左侧就是原始索引 [0,1,2,0,1,2],而如果使用join="inner"则只会保留重合的B列 同时Concat还支持DataFrame 与Series的混合拼接,例如: sr1 = pd.Series([1,2,3],name=”sr1″) sr2 = pd.Series([6,7,8,],name=”sr2″) print(pd.concat([sr1,df1,df2,sr2],axis=1)) # 混合拼接 输出结果为:    sr1  A  B  B   F  sr20    1  1  6  4   9    61    2  2  7  5  10    72    3  3  8  6  11    8
  • 目录
    • 一、排序
      • 1.1 对Series排序
      • 1.2 对DataFrame排序
    • 二、字符串和日期处理
      • 三、DataFrame的连接
        • 四、EXCEL表格批量合并和拆分
          • 4.1 批量进行表格合并
          • 4.2 批量进行表格拆分

        之前我们已经介绍了 pandas的基础使用用法,这一期我们来看看这个包其他有意思的方法

        Series的排序,主要是两个参数,一个是ascending,代表是否升序排列,另一个就是很熟悉的inplace

        sr = pd.Series([2,3,8,4,5])
        sr.sort_values(ascending=False,inplace=True) # 降序排序,同时替换原有DataFrame
        print(sr)
        

        输出的结果为,注意排序后index的顺序也会跟着变:

        2    8
        4    5
        3    4
        1    3
        0    2
        dtype: int64

        由于DataFrame是二维的,因此排序时多了一个参数by,表示按照哪一列进行排序,同时ascending也支持布尔数组,实现多条件的排序,如下:

        df = pd.DataFrame({"A":["B","A","B","B","A"],
                            "B":[2,3,8,4,5],
                            "C":[11,2,7,4,5]})
        # 单条件排序
        df.sort_values(by="B",ascending=True,inplace=True)
        print(df)
        

        单条件的排序结果为:

            A  B   C
        0  B  2  11
        1  A  3   2
        3  B  4   4
        4  A  5   5
        2  B  8   7

        而对于多条件排序,byascending一一对应,代表应该是升序还是降序

        # 多条件排序
        df.sort_values(by=["A","B"],ascending=[False,True],inplace=True)
        print(df)
        

        多条件排序输出结果如下,首先按照A列降序排序,然后按照B列升序排序,所以有一个主次的关系:

           A  B   C
        0  B  2  11
        3  B  4   4
        2  B  8   7
        1  A  3   2
        4  A  5   5

        对于字符串的处理,我们一般都使用str进行,而对于日期,我们用dt,直接通过底下的代码我们来看

        df = pd.DataFrame({"姓名":["张三","李四","王五","赵六","王二"],
                            "出生日期":["2000-01-01","2001-02-02","2002-03-03","2003-04-04","2004-05-05"],
                            "分数":["90分","29分","78分","46分","57分"]})
        print(df.dtypes)
        print("="*30)
        df["出生日期"] = pd.to_datetime(df["出生日期"]) # 转换为日期类型
        print(df["出生日期"].dtype) # datetime64[ns]
        # df["出生日期"] = df["出生日期"].str.replace("1","") # 错误用法,str只能为字符串服务
        df["出生日期"] = df["出生日期"].dt.strftime("%Y-%m-%d") # 转换为字符串类型
        print(df["出生日期"].dtype) # object
        df["分数"] = df["分数"].str.replace("分","").astype(int) # 转换为整数类型
        print(df)
        

        输出如下,我们一个一个做分析,首先我们定义了一个DataFrame,可以发现初始都是字符串,因此输出为object,然后我们通过to_datetime将其改成了标准的日期格式,因此输出为datetime64[ns],同样我们也可以通过dt.strftime将其转换为字符串格式,对于字符串格式,我们可以使用str下的若干方法进行处理,上述演示中只是将“分”这个字删除,并转换为整型:

        姓名      object
        出生日期    object
        分数      object
        dtype: object
        ==============================
        datetime64[ns]
        object
           姓名        出生日期  分数
        0  张三  2000-01-01  90
        1  李四  2001-02-02  29
        2  王五  2002-03-03  78
        3  赵六  2003-04-04  46
        4  王二  2004-05-05  57

        同时pandas严格约定str只服务于字符串,如果对其他格式使用,则会报错,对于字符串的处理,还有一个很强大的工具就是正则表达式,我们同样可以使用正则表达式进行处理,但是注意使用regex=True告诉程序这个是正则表达式:

        # 常规复杂的三步替换
        df["出生日期"] = df["出生日期"].str.replace("年","").str.replace("月","").str.replace("日","")
        # 正则表达式替换
        df["出生日期"] = df["出生日期"].str.replace("[年月日]","",regex=True)
        

        如果需要做DataFrame的连接,我们常常使用concat方法,其重要的三个参数分别是

        • axis=0 代表按行连接,否则是按列连接
        • ignore_index=True 表示重新生成一个新的索引,否则保留原始索引
        • join="outer" 表示保留所有非重复字段,join="inner"则表示只保留重合字段
        df1 = pd.DataFrame({"A":[1,2,3],
                            "B":[6,7,8]})
        df2 = pd.DataFrame({"B":[4,5,6],
                            "F":[9,10,11]})
        print(pd.concat([df1,df2],axis=1))
        print(pd.concat([df1,df2],axis=0,ignore_index=True,join="outer"))
        

        输出结果为:

           A  B  B   F
        0  1  6  4   9
        1  2  7  5  10
        2  3  8  6  11
             A  B     F
        0  1.0  6   NaN
        1  2.0  7   NaN
        2  3.0  8   NaN
        3  NaN  4   9.0
        4  NaN  5  10.0
        5  NaN  6  11.0

        在输出中,如果 ignore_index=False ,左侧就是原始索引 [0,1,2,0,1,2],而如果使用join="inner"则只会保留重合的B列

        同时Concat还支持DataFrameSeries的混合拼接,例如:

        sr1 = pd.Series([1,2,3],name="sr1")
        sr2 = pd.Series([6,7,8,],name="sr2")
        
        print(pd.concat([sr1,df1,df2,sr2],axis=1)) # 混合拼接
        

        输出结果为:

           sr1  A  B  B   F  sr2
        0    1  1  6  4   9    6
        1    2  2  7  5  10    7
        2    3  3  8  6  11    8

        之前我们已经学习了那么多的pandas使用技巧,那么接下来我们就看看上面讲到的比如Concat在实际过程中有什么用吧,比如我们先看一下批量的合并,既然要合并,不过就是DataFrame的拼接,在某个文件夹下有若干个xlsx文件,我们需要合并到一张表里,这些子表的表头都是相同的:

        那么我们通过下面的程序进行合并,首先获取文件夹下所有的xlsx文件,然后读取DataFrame,紧接着添加一个标识列,代表从哪个数据表中拿到的,最后合并并保存,在这里Concat就起到了将各个DataFrame合并在一起的功能

        son_file_path = r"C:Users22330Desktop进行中子文件"
        file_to_save = r"C:Users22330Desktop进行中Data_combine.xlsx"
        df_lists = [] # 用于存储每个子文件的DataFrame
        for item in os.listdir(son_file_path):
            if item.endswith(".xlsx"):
                file_path = os.path.join(son_file_path,item)
                df = pd.read_excel(file_path)
                df["son_id"] = item.split(".")[0] # 提取子文件的id作为新的一列
                df_lists.append(df) # 将当前子文件的DataFrame添加到列表中
        # 使用Concat合并所有子文件的DataFrame
        pd.concat(df_lists,axis=0).to_excel(file_to_save,index=False)
        

        最后输出的文件中,就会多出我们新增的一列son_id,整个的处理非常迅速。

        既然已经讲了合并,我们顺手也来看看拆分,我们的拆分需求是将表格平均分到若干个表里,在下面的程序中,我通过son_file_num 定义了要拆分的个数,通过考虑了除不尽的情况,然后依次按索引取值,放到每个表中

        import pandas as pd
        import os
        
        file_path = r"C:Users22330Desktop进行中Data.xlsx"
        save_path = r"C:Users22330Desktop进行中子文件"
        if not os.path.exists(save_path): # 如果子文件目录不存在,就创建一个
            os.mkdir(save_path)
        df = pd.read_excel(file_path)
        print(df.head(3)) # 查看前3行数据
        print(df.shape) # 查看数据条数和特征数
        
        son_file_num = 4
        son_file_size = df.shape[0] // son_file_num # 每个子文件的数据条数
        if df.shape[0] % son_file_num != 0: # 如果数据条数不能被子文件数整除,需要额外增加一条数据
            son_file_size += 1
        
        for i in range(son_file_num):
            start = i * son_file_size
            end = start + son_file_size
            df_son = df.iloc[start:end] # 这里的end是不包含在切片中的,所以不需要-1
            df_son.to_excel(f"{save_path}{file_path.split('.')[1]}_{i}.xlsx",index=False)
        

        命令行输出了我们的一些调试信息,可想而知,会按152:152:152:150 的比例分配数据,实现拆分

                出库日期       产品经理  产品类别  地区 安全等级  销售额(元)  销售数量  客户评分
        0 2023-06-01      Jerry  电子产品  西南    C  3789.6    12   5.0
        1 2023-06-02       Cary    服装  华东    A  2345.3    14   5.0
        2 2023-06-03  Bob-Smith  家居用品  西北    D   567.8     7   3.7
        (606, 8)

        到此这篇关于Pandas基础使用指南之排序、字符串日期处理和文件合并拆分技巧的文章就介绍到这了,更多相关Python Pandas使用内容请搜索风君子博客以前的文章或继续浏览下面的相关文章希望大家以后多多支持风君子博客!

        您可能感兴趣的文章:

        • Python对列表进行排序的5种实现方式
        • Python中给字典排序的七种方法详解
        • Python给对象数组排序的方法实现
        • Python字符串处理方法超全攻略
        • Python如何处理多分隔符的字符串拆分
        • Python处理字符串中文(汉字)编码的实例
        • pandas批量拆分与合并Excel文件的实现示例

        站内搜索