Python 数据帧的可变块大小

Python 数据帧的可变块大小,python,pandas,Python,Pandas,我有一个非常大的DF,其中包含如下数据: import pandas as pd df = pd.DataFrame() df['CODE'] = [1,2,3,1,2,4,2,2,4,5] df["DATA"] = [ 'AA', 'BB', 'CC', 'DD', 'AA', 'BB', 'EE', 'FF','GG', 'HH'] df.sort_values('CODE') df CODE DATA 0 1 AA 3 1 DD 1 2 BB

我有一个非常大的DF,其中包含如下数据:

import pandas as pd
df = pd.DataFrame()
df['CODE'] = [1,2,3,1,2,4,2,2,4,5]
df["DATA"] = [ 'AA', 'BB', 'CC', 'DD', 'AA', 'BB', 'EE', 'FF','GG', 'HH']
df.sort_values('CODE')
df
  CODE DATA
 0     1   AA
 3     1   DD
 1     2   BB
 4     2   AA
 6     2   EE
 7     2   FF
 2     3   CC
 5     4   BB
 8     4   GG
 9     5   HH
由于大小的原因,我需要将其拆分为块并对其进行解析。 但是,代码列中包含的equals元素不应以不同的块结束,而应将这些元素添加到上一个块中,即使超出了大小

基本上,如果我选择4行的块大小,第一个块可以增加到包含所有带有“2”和be的元素:

我发现了一些关于分块和分组的帖子,如下所示:

import pandas as pd
df = pd.DataFrame()
df['CODE'] = [1,2,3,1,2,4,2,2,4,5]
df["DATA"] = [ 'AA', 'BB', 'CC', 'DD', 'AA', 'BB', 'EE', 'FF','GG', 'HH']
df.sort_values('CODE')
df
  CODE DATA
 0     1   AA
 3     1   DD
 1     2   BB
 4     2   AA
 6     2   EE
 7     2   FF
 2     3   CC
 5     4   BB
 8     4   GG
 9     5   HH

然而,上面提供了一个相同大小的分块,我需要一个考虑到代码列中的值的智能分块


你知道怎么做吗?

我想你可以创建一个新的列
by,然后再除以
N
-为每个
code
值获取块:

N = 2
df['GROUPS'] = df.groupby('CODE').cumcount() // N
print (df)
   CODE DATA  GROUPS
0     1   AA       0
3     1   DD       0
1     2   BB       0
4     2   AA       0
6     2   EE       1
7     2   FF       1
2     3   CC       0
5     4   BB       0
8     4   GG       0
9     5   HH       0

groups = df.groupby(['CODE','GROUPS'])
for (frameno, frame) in groups:
    print (frame.to_csv("%s.csv" % frameno))

您还可以创建新的
系列
,并将其用于
groupby

chunked_ser = df.groupby('CODE').cumcount() // N
print (chunked_ser)
0    0
3    0
1    0
4    0
6    1
7    1
2    0
5    0
8    0
9    0
dtype: int64

groups = df.groupby([df.CODE,chunked_ser])
for (frameno, frame) in groups:
    print (frame.to_csv("%s.csv" % frameno))

我可能想出了一个解决方案(仍在测试所有案例),但不是很优雅

我创建了一个递归函数,返回要采取的间隔:

def findrange(start,step):
        for i in range(start,len(df)+1, step):
            if i+step > len(df): return [i, len(df)]
            if df.CODE[i+step:i+step+1].values != df.CODE[i+step-1:i+step].values:
                return [i,i+step]
        else:
            return findrange(i,step+1)
然后我调用函数获取范围并处理数据

interval = [0,0]
idx = 0
N=2
while interval[1] < len(df):
    if idx < interval[1]: idx = interval[1]
    interval = findrange(idx, N)
    idx+=N # this point became useless once interval[1] > idx 
interval=[0,0]
idx=0
N=2
当间隔[1]idx,该点就变得无用
我尝试了使用许多不同的N>0值发布的DF,看起来不错。
如果你有一个更像熊猫的方法,我对此持开放态度。

但以N=2为例,我最终将代码等于2的行拆分。我理解你的问题,你需要按
code
列将每个组拆分为更多组,因为数据量很大。因此,您可以使用大的
N
如1000-然后按1000行块分割。或者我遗漏了什么?如果使用楼层划分,例如尝试
N=3
获取大小为
1
的最后一组-获取大多数组的相同长度,但最后一组可以明显更小。