分别循环遍历数据框的每一列

时间:2017-08-16 22:10:22

标签: python function pandas loops dataframe

我目前正在使用从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]

我将以下操作应用于列' ACBA'

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... 

我不了解如何设置循环以便分别考虑每个列。稍后在我的代码中,我将不得不将其他操作应用于同一数据帧,因此我想了解底层逻辑(而不是查找与频率相关的函数)。谢谢

2 个答案:

答案 0 :(得分: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

答案 1 :(得分:0)

我确信有一种更有效的方法(例如,通过将所有列的频率存储在单个Dataframe中,以便您可以避免循环操作)。但是,如果您真的想为每列创建单独的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}

您可以使用ACBA_df = df_dict['ACBA']来检索您感兴趣的df。