我目前正在使用从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...
我不了解如何设置循环以便分别考虑每个列。稍后在我的代码中,我将不得不将其他操作应用于同一数据帧,因此我想了解底层逻辑(而不是查找与频率相关的函数)。谢谢
答案 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。