Как создать несколько фреймов данных, используя несколько функций - PullRequest
7 голосов
/ 12 января 2020

Я довольно часто пишу функцию, которая возвращает разные кадры данных на основе параметров, которые я ввожу. Вот пример dataframe:

np.random.seed(1111)
df = pd.DataFrame({
'Category':np.random.choice( ['Group A','Group B','Group C','Group D'], 10000),
'Sub-Category':np.random.choice( ['X','Y','Z'], 10000),
'Sub-Category-2':np.random.choice( ['G','F','I'], 10000),
'Product':np.random.choice( ['Product 1','Product 2','Product 3'], 10000),
'Units_Sold':np.random.randint(1,100, size=(10000)),
'Dollars_Sold':np.random.randint(100,1000, size=10000),
'Customer':np.random.choice(pd.util.testing.rands_array(10,25,dtype='str'),10000),
'Date':np.random.choice( pd.date_range('1/1/2016','12/31/2018',  
                      freq='M'), 10000)})

Затем я создал функцию для выполнения промежуточных итогов для меня следующим образом:

def some_fun(DF1, agg_column, myList=[], *args):
    y = pd.concat([
    DF1.assign(**{x:'[Total]' for x in myList[i:]})\
            .groupby(myList).agg(sumz = (agg_column,'sum')) for i in range(1,len(myList)+1)]).sort_index().unstack(0)
    return y

Затем я выписываю списки, которые я передам в качестве аргументов. к функции:

list_one = [pd.Grouper(key='Date',freq='A'),'Category','Product']
list_two = [pd.Grouper(key='Date',freq='A'),'Category','Sub-Category','Sub-Category-2']
list_three = [pd.Grouper(key='Date',freq='A'),'Sub-Category','Product']

Затем я должен запустить каждый список через свою функцию, создавая новые кадры данных:

df1 = some_fun(df,'Units_Sold',list_one)
df2 = some_fun(df,'Dollars_Sold',list_two)
df3 = some_fun(df,'Units_Sold',list_three)

Затем я использую функцию, чтобы записать каждый из этих кадров данных в Excel Рабочий лист. Это всего лишь пример - я выполняю это упражнение более 10 раз.

Мой вопрос - есть ли лучший способ выполнить эту задачу, чем выписать df1, df2, df3 с примененной информацией о функциях? Должен ли я использовать словарь или другой тип данных, чтобы сделать это с помощью функции?

Ответы [ 2 ]

3 голосов
/ 15 января 2020

Словарь будет моим первым выбором:

variations = ([('Units Sold', list_one), ('Dollars_Sold',list_two), 
              ..., ('Title', some_list)])

df_variations = {}

for i, v in enumerate(variations):
     name = v[0]
     data = v[1]
     df_variations[i] = some_fun(df, name, data)

Вы могли бы также рассмотреть возможность установки ключей для уникальных / полезных названий для вариантов, которые выходят за рамки чего-то вроде «Проданные единицы», что не является уникальный в вашем случае.

1 голос
/ 19 января 2020

IIU C,

, как предположил Томас, мы можем использовать словарь для анализа ваших данных, но с некоторыми незначительными изменениями в вашей функции мы можем использовать словарь для хранения всех необходимые данные затем передают их в вашу функцию.

идея состоит в том, чтобы передать два типа ключей, список столбцов и аргументы для вашего pd.Grouper вызова.

data_dict = {
    "Units_Sold": {"key": "Date", "freq": "A"},
    "Dollars_Sold": {"key": "Date", "freq": "A"},
    "col_list_1": ["Category", "Product"],
    "col_list_2": ["Category", "Sub-Category", "Sub-Category-2"],
    "col_list_3": ["Sub-Category", "Product"],
}

def some_fun(dataframe, agg_col, dictionary,column_list, *args):

    key = dictionary[agg_col]["key"]

    frequency = dictionary[agg_col]["freq"]

    myList = [pd.Grouper(key=key, freq=frequency), *dictionary[column_list]]

    y = (
        pd.concat(
            [
                dataframe.assign(**{x: "[Total]" for x in myList[i:]})
                .groupby(myList)
                .agg(sumz=(agg_col, "sum"))
                for i in range(1, len(myList) + 1)
            ]
        )
        .sort_index()
        .unstack(0)
    )
    return y

Test.

df1 = some_fun(df,'Units_Sold',data_dict,'col_list_3')
print(df1)
                                 sumz                      
Date                   2016-12-31 2017-12-31 2018-12-31
Sub-Category Product                                   
X            Product 1      18308      17839      18776
             Product 2      18067      19309      18077
             Product 3      17943      19121      17675
             [Total]        54318      56269      54528
Y            Product 1      20699      18593      18103
             Product 2      18642      19712      17122
             Product 3      17701      19263      20123
             [Total]        57042      57568      55348
Z            Product 1      19077      17401      19138
             Product 2      17207      21434      18817
             Product 3      18405      17300      17462
             [Total]        54689      56135      55417
[Total]      [Total]       166049     169972     165293

Если вы хотите автоматизировать написание 10-кратных листов, мы можем снова сделать это с помощью словарного вызова для вашей функции:

matches = {'Units_Sold': ['col_list_1','col_list_3'],
          'Dollars_Sold' : ['col_list_2']}

затем просто для l oop записать все файлы на один лист Excel, измените его в соответствии с требуемым поведением.

writer = pd.ExcelWriter('finished_excel_file.xlsx')
for key,value in matches.items():
    for items in value:        
        dataframe = some_fun(df,k,data_dict,items)
        dataframe.to_excel(writer,f'{key}_{items}')
writer.save()
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...