2017-08-16 83 views
1

我目前正在使用从Excel导入的数据框。数据帧的头看起来是这样的:分别循环遍历数据帧的每一列

CRED ACBA PAYMS PUR 
0  0  2 2 2 
1  0  4 2 2 
2  0  1 2 3 
3  1  1 2 2 
4  0  2 4 3 

我再这个数据帧到一个较小的数据帧进行时CRED = 1

df_CRED1 = df_original[df_original.CRED == 1] 

我采用下列操作栏“木神”

list_frequency_cred1 = [df_CRED1['ACBA'].value_counts()] 
frequency_cred1_total = sum(df_CRED1['ACBA'].value_counts()) 
matrix_frequency_cred1 = DataFrame(data = list_frequency_cred1) 
matrix_frequency_cred1['Total'] = frequency_cred1_total 
matrix_frequency_cred1.rename(index = {'ACBA':'CRED1'}, inplace=True) 

为了获得下表:

 1 2 3 4 Total 
CRED1 9 11 1 7  28 

我现在正在创建一个循环,将适用于以获得单独的频率表对每列我做了列ACBA所有其他列这样的操作顺序:

ACBA 
     1 2 3 4 Total 
CRED1 9 11 1 7  28 

PAYMS 
     1 2 3 4 Total 
CRED1 4 5 6 7  22 

etc... 

我不明白如何设置循环以便分别考虑每列。后来在我的代码中,我将不得不将其他操作应用于相同的数据框,所以我想了解基础逻辑(而不是查找与频率相关的函数)。谢谢

回答

0

我相信有这样做的更有效的方式(例如通过将所有列的频率存储在单个数据框中,以避免循环操作)。但是,如果你真的想独立DFS为每列,你可以做这样的事情:

cols = list(df.columns)[1:] # exclude CRED from list of cols to process 
df_dict = {} 
for col in cols: 
    df = <your operations to generate a df> 
    df_dict.update{col:df} 

您可以检索DF你有兴趣使用ACBA_df = df_dict['ACBA']例如。

+0

是,我肯定会在某个时候优化它。谢谢你的回答,它的工作! – Dine

1

它看起来这是你想要做什么,但愿这不是矫枉过正:

创建测试数据:

import pandas as pd 
import numpy as np 

df = pd.DataFrame(np.random.randint(0, 5, (150, 4)), columns=['CRED', 'ACBA', 'PAYMS', 'PUR']) 
df.loc[:, ['ACBA', 'PAYMS', 'PUR']] = df[['ACBA', 'PAYMS', 'PUR']].replace(0, np.nan) 
df.head() 

CRED ACBA PAYMS PUR 
0 4 1 2 NaN 
1 4 3 2 NaN 
2 1 NaN 1 3 
3 0 NaN NaN 3 
4 4 1 4 2 

计算值数:

def get_value_counts(grp): 
    """Compute value counts for each column in DataFrame subset.""" 
    return grp.drop('CRED', axis=1).apply(pd.value_counts) 

vc = df.groupby('CRED').apply(get_value_counts) 
vc.head() 

      ACBA PAYMS PUR 
CRED      
0 1.0  2  1 7 
    2.0  9  7 1 
    3.0  5  5 13 
    4.0  3  4 3 
1 1.0  7  7 6 

将值重新分类以包含总计:

vc = (vc 
     .reset_index(level=1) 
     .rename(columns={'level_1': 'VALUE'}) 
     .assign(VALUE=lambda frame: (frame.VALUE 
            .astype('int') 
            .astype('category') 
            .cat.add_categories(['Total']))) 
     .set_index('VALUE', append=True)) 
vc.columns.names = ['VARIABLE'] 
vc.head() 

VARIABLE ACBA PAYMS PUR 
CRED VALUE     
0 1   2  1 7 
    2   9  7 1 
    3   5  5 13 
    4   3  4 3 
1 1   7  7 6 

计算总量,并把 '总' 的标签列:

vc_totals = vc.groupby(level=0).sum().astype('int') 
idx = pd.MultiIndex.from_product([vc_totals.columns, ['Total']], names=['VARIABLE', 'VALUE']) 
vc_totals.columns = idx 
vc_totals.head() 

VARIABLE ACBA PAYMS PUR 
VALUE Total Total Total 
CRED      
0   19 17 24 
1   28 28 28 
2   27 22 26 
3   16 19 19 
4   33 31 26 

组合价值数及其汇总:

vc_results = vc.unstack(fill_value=0).join(vc_totals).sort_index(axis=1, level=0) 
vc_results 

VARIABLE ACBA     PAYMS     PUR     
VALUE  1 2 3 4 Total  1 2 3 4 Total 1 2 3 4 Total 
CRED                  
0   2 9 5 3 19  1 7 5 4 17 7 1 13 3 24 
1   7 7 5 9 28  7 9 6 6 28 6 9 8 5 28 
2   7 2 8 10 27  5 7 4 6 22 5 6 5 10 26 
3   5 6 3 2 16  5 4 6 4 19 4 5 4 6 19 
4   13 6 11 3 33  7 9 4 11 31 2 11 5 8 26 

如果你只是想CRED = 1:

vc_results.loc[1].unstack() 

VALUE  1 2 3 4 Total 
VARIABLE     
ACBA  7 7 5 9  28 
PAYMS  7 9 6 6  28 
PUR  6 9 8 5  28 
+0

谢谢你的回答!但那不是我想要的。我现在意识到,也许我的问题不是很好? CRED只能取值0或1,而每个变量(ACBA,PAYMS,PUR列)可能有4个以上的类别(例如:PAYMS可以是1 2 3 4 5 6 8 9 10)。我设法找到解决办法,如果您有兴趣,可以与您分享代码! – Dine

+0

无论类别(或VALUES)的数量多少,该解决方案都应该可以工作,我使用了一个伪造的数据集作为示例。 – dgoodman1