我想获取一个已分组的数据框,并为每个组分别创建单独的数据框。
我正在使用列表推导,使用列表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)
这种方法只会为每个值返回无列表。
我想要的结果是一个变量列表,并将数据帧的各个部分分配给每个变量。
答案 0 :(得分:4)
df = pd.DataFrame(dict(A=range(10), B=[*'aabbccddee']))
dict
将它们存储在字典中,而不是命名变量中
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
答案 1 :(得分: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
中,并根据需要进行初始化。