将数据框分割成分组块

4
我希望将一个数据框分成几个部分。我已经创建了一个函数,可以将数据框平均分成几部分,但是无法想出如何按组进行分割。
每个数据框的拆分必须包括所有组变量的实例,我希望可以灵活地选择包含多少个组(因为它们相对较小)。
示例数据框:
A  1
A  2
B  3
C  1
D  9
D  10

目标分割(至少包括两个组):

组1:

A  1
A  2
B  3

分裂 2:

C  1
D  9
D  10

如果需要的话,我的当前函数看起来像下面这样:

def split_frame(sequence, size=10000):
    return (sequence[position:position + size] for position in range(0, len(sequence), size))

需要帮助!


您是否想保留顺序?比如说您有4行A,然后9行B,再接着5行C。您是否希望将A与C分组?在原始数据框中,所有分组变量的实例是否都是连续的? - Acccumulation
顺序不重要,只要每个分组包含该组的所有元素即可。当然,这些组的长度会有所不同。分组变量是数据框中的随机数ID。 - shbfy
4个回答

6

适用于Python 2和3:

df = pd.DataFrame(data=['a', 'a', 'b', 'c', 'a', 'a', 'b', 'v', 'v', 'f'], columns=['A']) 

def iter_by_group(df, column, num_groups):
    groups = []
    for i, group in df.groupby(column):
        groups.append(group)
        if len(groups) == num_groups:
            yield pd.concat(groups)
            groups = []
    if groups:
        yield pd.concat(groups)

for group in iter_by_group(df, 'A', 2):
    print(group)

A
0  a
1  a
4  a
5  a
2  b
6  b

A
3  c
9  f

A
7  v
8  v

我理解你的问题了吗?那就是你所要求的吗? - Dennis Golomazov
我认为是这样的!只是测试它是否保留了分组 - 每个数据帧块必须包括组的每个实例(这是重要的事情)。我希望问题表述清楚了。感谢您的帮助! - shbfy
1
当然,假设我们希望每个数据框有两个组,我期望会有一个包含a、a、a、a、b、b的数据框 - 一个包含c、v、v的数据框和一个给定上述示例中的‘f’的数据框。 - shbfy
谢谢Dennis。这看起来没问题,但我认为你粘贴的代码在lambda函数附近有语法错误?编辑:我正在使用Python 3!抱歉!在lambda函数附近的元组解包是否有修复方法?谢谢。 - shbfy
1
我找到了一个更简单的解决方案并更新了答案。请尝试这个。 - Dennis Golomazov
显示剩余3条评论

3
这里是稍微快一点的版本。 它枚举了组并通过它们的组号返回它们。>
import pandas as pd

def group_chunks(df, column, chunk_size):
    df["n_group"] = df.groupby(column).ngroup()
    lower_group_index = 0
    upper_group_index = chunk_size - 1
    max_group_index = df["n_group"].max()
    while lower_group_index <= max_group_index:
        yield df.loc[:, df.columns != "n_group"][
            df["n_group"].between(lower_group_index, upper_group_index)
        ]
        lower_group_index = upper_group_index + 1
        upper_group_index = upper_group_index + chunk_size

df = pd.DataFrame(data=['a', 'a', 'b', 'c', 'a', 'a', 'b', 'v', 'v', 'f'], columns=['A']) 
for chunk in group_chunks(df, 'A', 2):
    print(f"{chunk.sort_values(by='A')}\n")

   A
0  a
1  a
4  a
5  a
2  b
6  b

   A
3  c
9  f

   A
7  v
8  v


1
这也应该可以工作:
n = 2
splits = {g:df for g,df in df.groupby(df.groupby('A').ngroup().floordiv(n))}

每个df都可以通过字典中的键进行访问。然后可以将它们连接回一个df,现在索引中显示了组。

pd.concat(splits,names = ['groups'])

0

各种方法的概览

def golomazov(df, column, num_groups):
    groups = []
    for i, group in df.groupby(column):
        groups.append(group)
        if len(groups) == num_groups:
            yield pd.concat(groups)
            groups = []
    if groups:
        yield pd.concat(groups)
        
def arigion(df, column, chunk_size):
    df["n_group"] = df.groupby(column).ngroup()
    lower_group_index = 0
    upper_group_index = chunk_size - 1
    max_group_index = df["n_group"].max()
    while lower_group_index <= max_group_index:
        yield df.loc[:, df.columns != "n_group"][
            df["n_group"].between(lower_group_index, upper_group_index)
        ]
        lower_group_index = upper_group_index + 1
        upper_group_index = upper_group_index + chunk_size

def rhug123(df, column, n):
    return {g: df for g, df in df.groupby(df.groupby('Symbol').ngroup().floordiv(n))}

def misantroop(df, column, num_groups):
    symbol_groups = df.groupby(column)
    groups = np.array_split(list(symbol_groups.groups), num_groups)
    for group in groups:
        yield pd.concat([symbol_groups.get_group(name) for name in group])

%timeit golomazov(df, 'Symbol', n)
157 ns ± 0.647 ns per loop (mean ± std. dev. of 7 runs, 10,000,000 loops each)
from pympler.asizeof = 414176

%timeit arigion(df, 'Symbol', n)
160 ns ± 0.903 ns per loop (mean ± std. dev. of 7 runs, 10,000,000 loops each)
from pympler.asizeof = 414176

%timeit rhug123(df, 'Symbol', n)
5.53 ms ± 28 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)
from pympler.asizeof = 57534096

%timeit misantroop(df, 'Symbol', num_groups=n*40)
191 ns ± 2.09 ns per loop (mean ± std. dev. of 7 runs, 1,000,000 loops each)
from pympler.asizeof = 414176

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接