Разбить сгруппированный фрейм данных на отдельные фреймы данных - PullRequest
0 голосов
/ 29 ноября 2018

Я бы хотел взять сгруппированный фрейм данных и создать отдельные фреймы данных для каждой соответствующей группы.

Я использую понимание списка, чтобы разрезать фрейм данных 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 для каждого значения.

Мой желаемый результат - список переменных с соответствующим срезомФрейм данных присваивается каждой переменной.

Ответы [ 2 ]

0 голосов
/ 29 ноября 2018

В зависимости от самих данных должно работать следующее:

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 инициализируется так, как вы хотите.

0 голосов
/ 29 ноября 2018

Настройка

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
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...