2016-12-17 3 views
1

Как передавать df10 и df20 (и даже больше данных) через func одновременно и сохранять имена для дальнейшего использования?передают несколько данных с помощью функции одновременно

import pandas as pd 
import numpy as np 

df = pd.DataFrame({ 
    'A': ['d','d','d','d','d','d','g','g','g','g','g','g','k','k','k','k','k','k'], 
    'B': [5,5,6,4,5,6,-6,7,7,6,-7,7,-8,7,-6,6,-7,50], 
    'C': [1,1,1,1,1,1,1,1,1,1,1,1,2,2,2,2,2,2], 
    'S': [2012,2013,2014,2015,2016,2012,2012,2014,2015,2016,2012,2013,2012,2013,2014,2015,2016,2014]  
    }); 

df10 = (df.B + df.C).groupby([df.A, df.S]).agg(['sum','size']).unstack(fill_value=0) 

df20 = (df['B'] - df['C']).groupby([df.A, df.S]).agg(['sum','size']).unstack(fill_value=0) 

def func(df): 
    df1 = df.groupby(level=0, axis=1).sum() 
    new_cols= list(zip(df1.columns.get_level_values(0),['total'] * len(df.columns))) 
    df1.columns = pd.MultiIndex.from_tuples(new_cols) 
    df2 = pd.concat([df1,df], axis=1).sort_index(axis=1).sort_index(axis=1, level=1) 
    df2.columns = ['_'.join((col[0], str(col[1]))) for col in df2.columns] 
    df2.columns = df2.columns.str.replace('sum_','') 
    df2.columns = df2.columns.str.replace('size_','T') 
    return df2 

EDIT, согласно запросу распечатанные датаграммы;

печать (DF10) печати (df20)

df10: 

    sum size 
S 2012 2013 2014 2015 2016 2012 2013 2014 2015 2016 
A          
d 13 6 7 5 6 2 1 1 1 1 
g -11 8 8 8 7 2 1 1 1 1 
k -6 9 48 8 -5 1 1 2 1 1 



df20: 

    sum size 
S 2012 2013 2014 2015 2016 2012 2013 2014 2015 2016 
A          
d 9 4 5 3 4 2 1 1 1 1 
g -15 6 6 6 5 2 1 1 1 1 
k -10 5 40 4 -9 1 1 2 1 1 

распечатки добавила

+0

Можете ли вы показать обновление кода с образцом того, что выглядят как df10 и df20? – Chuck

+0

Я думаю, что было бы проще всего с циклом 'for' над списком всех DataFrames, к которым вы хотите применить эту функцию. Хотя это зависит от того, что вы хотите сделать с этими DataFrames после 'func'. – josh

ответ

3

Edit: Существует, вероятно, гораздо лучший способ сделать это; Я просто подумал, что предлагаю это предложение. Если это не так, пожалуйста, дайте мне знать, и я удалю.

Как передать df10 и df20 (и даже больше данных) через func одновременно и сохранить их имена для дальнейшего использования?

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

Для простоты принять dataframes:

df10 = pd.DataFrame({'one' : [1., 2., 3., 4.], 'two' : [4., 3., 2., 1.]}) 
df20 = pd.DataFrame({'one' : [1., 2., 3., 4.], 'two' : [4., 3., 2., 1.]}) 
df30 = pd.DataFrame({'one' : [1., 2., 3., 4.], 'two' : [4., 3., 2., 1.]}) 

и простую функцию:

your_func(df): 
    #### Perform some action/change to df eg 
    df2 = df.head(1) 
    return df2 

Создать список вашего оригинального dataframes:

A = [df10,df20,df30] 

A = [ one two 
    0 1.0 4.0 
    1 2.0 3.0 
    2 3.0 2.0 
    3 4.0 1.0,  
     one two 
    0 1.0 4.0 
    1 2.0 3.0 
    2 3.0 2.0 
    3 4.0 1.0,  
     one two 
    0 1.0 4.0 
    1 2.0 3.0 
    2 3.0 2.0 
    3 4.0 1.0] 

Затем, используйте цикл передавать каждый кадр данных через список, например Это не изменит ваши исходные данные.

for i in range(0,len(A)): 
    A[i] = your_func(A[i]) 

Выход:

A = [ 
one two 
0 1.0 4.0, 
one two 
0 1.0 4.0, 
one two 
0 1.0 4.0] 

Итак, теперь список A содержит каждый из новых dataframes. И ваши исходные dataframes df10df20 и т. Д. Остаются без изменений. Просто позвоните элементам A, чтобы получить доступ к новым данным.

+2

В качестве альтернативы используйте карту: 'newA = map (your_funct, A)' или понимание списка: 'newA = [your_func (i) для i в A]' – Parfait

+0

@Parfait - Ваш путь намного чище и эффективнее. Я всегда забываю о карте. Спасибо за комментарий: Я тоже учусь. – Chuck

+0

Спасибо, ребята, однако мне нужно изменить df и иметь возможность называть их индивидуально после согревания. – Zanshin

Смежные вопросы