将分组的数据框拆分为单独的数据框

4
我想要对已分组的数据框进行处理,将每个组分别创建成不同的数据框。
我使用列表推导式,在pandas数据框中使用列表names_list的值进行切片,然后将结果赋值给同名变量。但是,names_list中的值并不总是出现在我的数据框中,而且哪一个值不在数据框中是完全随机的。如何使此方法生效并仅返回实际出现的变量?
我尝试了以下方法:
idx = pd.IndexSlice

names_list = ['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h']
a, b, c, d, e, f, g, h = [df.loc[idx[x,:],:] for x in names_list]

当数据框中不存在某个值时,上述代码会返回KeyError错误。

还尝试了以下方法:

def split_df(data):
    try:
        a = [df.loc[idx[x,:],:] for x in data]
    except KeyError:
        a = None
    return a


names_list = ['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h']
a, b, c, d, e, f, g, h = [x for x in names_list]
name_vars = [a, b, c, d, e, f, g, h]

name_vars_2 = []
for var, val in zip(name_vars,names_list):
    var = split_df(val)
    if var is None:
        continue
    else:
        name_vars_2.append(var)

这种方法只返回每个值的 None 列表。

我希望得到一个变量列表,每个变量对应数据框的相应切片。


1
我正在使用列表推导式,通过列表names_list中的值来切片pandas数据框,并将结果分配给同名变量。我只是不理解这种用例。这肯定是XY问题的杰作吧? - roganjosh
这没有用例。如果您想要一个可变数量的变量,可以使用groupby,并可选地使用dict。这几乎肯定是XY问题。请解释您潜在的问题,我们可能能够提供帮助。 - jpp
我已经在主数据框上执行了groupby操作。现在我想将主数据框拆分为每个组的单独数据框。 - DH_III
2个回答

5

设置

df = pd.DataFrame(dict(A=range(10), B=[*'aabbccddee']))

字典

将它们存储在字典中而不是命名变量

d = dict((*df.groupby('B'),))

d['a']

   A  B
0  0  a
1  1  a

d['d']

   A  B
6  6  d
7  7  d

不建议使用!

但是为了您的教育,您可以更新locals()字典。
这是不好的,因为动态污染命名空间会导致许多难以跟踪的错误。
事实上,它不能保证做任何事情。

根据文档

注意:不应更改此字典的内容;更改可能不会影响解释器使用的局部变量和自由变量的值。

放弃免责声明,以下是您可以执行的操作:

locals().update(dict((*df.groupby('B'),)))

然后访问命名变量。
a

   A  B
0  0  a
1  1  a

d

   A  B
6  6  d
7  7  d

0
根据数据本身,以下内容应该可以工作。
from string import ascii_lowercase, ascii_uppercase
import pandas as pd 
import numpy as np 

n0, n1 = 8, 3
midx = pd.MultiIndex.from_product([list(ascii_lowercase[:n0]),
                                   list(ascii_uppercase[:n1])])
columns = ['foo', 'bar']
arr = np.arange(n0*n1*len(columns)).reshape((len(midx),len(columns)))
all_df = pd.DataFrame(arr, index=midx, columns=columns)
sub_df = all_df.query('foo < 12 or foo > 16').query('foo < 42')
vals = lambda df, idx, l: {c: df.loc[idx[c, :], :] for c in l}

不要直接分配变量,使用字典并查看整个数据集以及删除一部分后的结果。

all_vals = vals(all_df, pd.IndexSlice, list(ascii_lowercase[:n0]))
sub_vals = vals(sub_df, pd.IndexSlice, list(ascii_lowercase[:n0]))

例如,

>>> all_vals['a']
     foo  bar
a A    0    1
  B    2    3
  C    4    5

>>> sub_vals['a']
     foo  bar
a A    0    1
  B    2    3
  C    4    5

但是,

>>> all_vals['c']
     foo  bar
c A   12   13
  B   14   15
  C   16   17

>>> sub_vals['c']
Empty DataFrame
Columns: [foo, bar]
Index: []

最后,您可以使用类似于[... for x in lst if x in df.index.levels [0] .values]的语句来过滤理解,并可能将值存储在初始化为所需方式的collections.defaultdict中。


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