对于pandas数据进行均分分块和合并

pandas并未内置分块函数,对于pandas的分块有2种方法,一种是通过numpy中的split分块和本文介绍的自动计算分块行数进行分块的方法。在合并的时候主要也是解决无列名或列名不一致时的合并。

一、分块

分块有均分和非均分两种,对于已经读取了df信息的数据,转化为numpy进行分块较为方便,参考下面文章。
https://zhuanlan.zhihu.com/p/524033078
对于未读取df信息的数据,如只知道最大的行数需要等分的情况(常见于各种懒加载中,只加载了数据表结构但是未加载信息)可以使用如下等分方法。
分块方法:
先把余数行数放在最后,其余每个分块按照均分的数量作为步长进行分配。
chunk_size是每个块的大小,也是每次分块的步长。max_row // n 其中// 是除法向下取整,得到一个整数的步长。
mode_size 是对最大行数按n整除后的余数,对于不能整除的组后一个块是 tuple_max = (max_row - mode_size, mode_size)

chunk_size = max_row // n
mode_size = max_row % n

将分块数据放在列表中用于下一步的遍历,列表中的元素为元组。元组的两个元素分别用于每次读取excel的起始位置和读了多少行skiprows=start, nrows=row_num_read。

注意:分块的for循环中range(n+1)是n+1,因为第n个块有数据,但是range(n)不包括n。

def chunk_size_list(max_row, n):
    lst = []
    chunk_size = max_row // n
    mode_size = max_row % n
    if mode_size == 0:
        for i in range(n+1):# 是n+1,因为第n个块有数据,但是range(n)不包括n
            lst.append(((i * chunk_size, chunk_size)))

    if mode_size > 0:
        for i in range(n+1): 
            lst.append(((i * chunk_size, chunk_size)))
        tuple_max = (max_row - mode_size, mode_size)
        lst.append(tuple_max)

    return lst

二、数据合并

使用pandas合并数据,要求列名一致,使用numpy合并数据要求维度一致;np合并数据效率更高。使用pandas,对于各数据块列名不一致的情况,需要制作统一的列名,再合并。

采用numpy合并的方式
使用numpy 需要对齐维度再合并。

4.1 当各块数据维度一致时,分块读取的数据,第一列有列名后面的df没有列名,需要转化为np再合并,再转为df,否则会把各df的第一行当做列名,然后对齐。

下面results是一个列表,每个元素都是一个df,其中第一个有列名,后面的没有,使用如下方法。

    col = results[0].columns
    res = [i.values for i in results]
    data_np= np.concatenate(res)
    pf = pd.DataFrame(data_np, columns=col)

4.2 当各数据块维度不一致时,维度不一致主要是由于整个数组都是空行,或者列的数量不一致(以按行叠加合并为例子,部分块的列比其他块的列多,比如有的块30行,有的块50行)。
剔除空行和给有列名无数据的列进行填充

for i in ls_df:
    np_i=i.values
    a,b=np_i.shape[0],np_i.shape[1]
#获取最大的列号,用于下一步的填充,即对最大的列号,没数据的填充nan
    if a*b!=0: #剔除空行和空列
        lst_np.append(np_i)
        lst_col_n.append(b)

#对于只有部分行有数据的列进行填充,对齐维度,否则无法合并
max_c = max(lst_col_n)
d_np=[]
for j in lst_np:
    if j.shape[1]

你可能感兴趣的:(Python常用小框架,pandas,python,数据分析)