【问题标题】:Having trouble splitting a dataframe into fixed chunks (per row)无法将数据帧拆分为固定块(每行)
【发布时间】:2020-09-19 20:15:48
【问题描述】:

我已经阅读了这个网站上关于将 pandas 数据帧拆分为固定大小的块的几个主题,但是我遇到了一个我没有在这里看到的问题。所以这里是这个过程:我询问用户他希望有多少块的输入,然后询问每个块分配的数据帧的百分比,我验证给定的百分比不超过 1,然后进行相应的拆分.以下是最后一部分,我正在努力解决的问题:

def dataframe_splitting(df:pd.DataFrame, fracs:list):
    split_frac = []
    print('Size of the dataframe:', df.shape)
    print('fracs:', fracs)
    for i in fracs:
        x = int(i*len(df))
        split_frac.append(x)
    print('split_frac:', split_frac)
    chunks = np.array_split(df, split_frac)
    for x in chunks:
        print(x.shape)
    return chunks

这是当参数为:5 个块和碎片 = [0.1, 0.1, 0.3, 0.2] 时给出的结果

Size of the dataframe: (2122905, 79)
fracs: [0.1, 0.1, 0.3, 0.2]
split_fracs: [212290, 212290, 636871, 424581]
(212290, 79)
(0, 79)
(424581, 79)
(0, 79)
(1698324, 79)

如您所见,对于相同的参数 (0.1),我有一个数据帧,其行数为 212290,其后的数据帧为空。我一开始尝试使用 np.split,结果没有什么不同。我真的不知道这段代码哪里错了,为什么会这样。

【问题讨论】:

    标签: python pandas


    【解决方案1】:

    根据np.array_splitdocumentation,第二个参数indices_or_sections指定块边界而不是块大小。即,如果我们传递一个长度为N 的第一个轴的数组和一个带有K 元素的列表fracs,则生成的块将对应于索引[0, fracs[0])[fracs[0], fracs[1])、...、[fracs[K-1], N) .因此,如果fracs 的两个连续元素相等,则会产生大小为 0 的块。

    为达到预期结果对代码的最小修改是在生成的 split_frac 变量上调用 np.cumsum

    def dataframe_splitting(df:pd.DataFrame, fracs:list):
        split_frac = []
        print('Size of the dataframe:', df.shape)
        print('fracs:', fracs)
        for i in fracs:
            x = int(i*len(df))
            split_frac.append(x)
        chunks = np.array_split(df, np.cumsum(split_frac))  # note the cumsum here
        for x in chunks:
            print(x.shape)
        return chunks
    

    【讨论】:

    • 感谢您的澄清!它按预期工作
    【解决方案2】:

    为了分割成不同大小的数据帧,使用 iloc 并遍历计算生成的范围可能更容易。我做了类似的事情来计算每帧的行数,然后使用循环和计数器来跟踪开始和停止行索引。

    这是一个示例数据框,您可以使用 pd.read_clipboard() 复制和阅读

    我打印了每个数据帧的结果,但您可以随意使用它们。

        a       b           c
    1   43.91   -0.041619   43.91
    2   43.39   0.011913    43.91
    3   45.56   -0.048801   43.91
    4   45.43   0.002857    43.91
    5   45.33   0.002204    43.91
    6   45.68   -0.007692   43.91
    7   46.37   -0.014992   43.91
    8   48.04   -0.035381   43.91
    9   48.38   -0.007053   43.91
    
    
    fracs = [0.1, 0.1, 0.3, 0.2]
    
    start = 0
    for x in [round(df.shape[0]*x) for x in fracs]:
        print(df.iloc[start:start+x])
        start += x  
    

    输出

           a         b      c
    1  43.91 -0.041619  43.91
           a         b      c
    2  43.39  0.011913  43.91
           a         b      c
    3  45.56 -0.048801  43.91
    4  45.43  0.002857  43.91
    5  45.33  0.002204  43.91
           a         b      c
    6  45.68 -0.007692  43.91
    7  46.37 -0.014992  43.91
    

    【讨论】:

    • 也感谢您提供的方法,它非常有效!遗憾的是,我无法将 2 cmets 标记为有效答案
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-08-10
    • 1970-01-01
    • 2013-11-16
    相关资源
    最近更新 更多