返回所有或特定列的频率计数的函数



我可以返回一个漂亮的数据帧中所有列的频率,其中包含一个总列。

for column in df:     
df.groupby(column).size().reset_index(name="total")
Count   total
0   1   423
1   2   488
2   3   454
3   4   408
4   5   343
Precipitation   total
0   Fine        7490
1   Fog         23
2   Other       51
3   Raining     808
Month   total
0   1   717
1   2   648
2   3   710
3   4   701

我把循环放在一个函数中,但这会返回第一列";计数";只有

def count_all_columns_freq(dataframe_x):
for column in dataframe_x:
return dataframe_x.groupby(column).size().reset_index(name="total")
count_all_columns_freq(df)
Count   total
0   1   423
1   2   488
2   3   454
3   4   408
4   5   343

有没有一种方法可以使用切片或其他方法来做到这一点,例如for column in dataframe_x[1:]:

根据您的评论,您只想返回一个数据帧列表:

def count_all_columns_freq(df):
return [df.groupby(column).size().reset_index(name="total")
for column in df]

您可以在pandas中以多种方式选择列,例如通过切片或传递列列表(如df[['colA', 'colB']](。您不需要为此更改函数。

就我个人而言,我会退回一本字典:

def frequency_dict(df):
return {column: df.groupby(column).size()
for column in df}
# so that I could use it like this:
freq = frequency_dict(df)
freq['someColumn'].loc[value]

编辑:"如果我想计算NaN的数量怎么办">

在这种情况下,您可以将dropna=False传递给groupby(这适用于pandas >= 1.1.0(:

def count_all_columns_freq(df):
return [df.groupby(column, dropna=False).size().reset_index(name="total")
for column in df]

您可以使用concat和一些重命名从按大小分组的创建数据帧。

首先获取您想要的列,例如:

cols = df.columns 

然后使用concat将它们拼接在一起,将keys定义为列(新索引(并且将names定义为"列";组";以及";尺寸";,这是他们显示的名字。

res = pd.concat((df.groupby(col, dropna=False).size() for col in cols, keys=cols, names=["indices", "groups"])

现在,我们希望这个集合在一个数据帧中,而不是一个系列中。

res = pd.DataFrame(res)

最后,我们将总数重命名为

res = res.rename(columns={0 : "totals"})

示例:

import pandas as pd
import numpy as np
rng = np.random.default_rng() # random number generation
A = rng.choice(["a", "b", "c"], 50)
B = rng.choice(["e", "f", "d"], 50)
C = rng.choice(['1', '2', '3', '5', '11'], 50)
df = pd.DataFrame({"A":A, "B":B, "C":C})
cols = df.columns
res = pd.DataFrame(pd.concat((df.groupby(c, dropna=False).size() for c in cols),  
keys=cols, names=["indices", "groups"]))
res = res.rename(columns = {0 : "totals"})

输出:

totals
indices groups        
A      a          16
b          17
c          17
B      d           9
e          22
f          19
C      1          10
11         16
2           8
3          10
5           6

创建相关功能可以这样做:

def concat_groups(df, cols=None):
if cols is None:
cols = df.columns
res = pd.DataFrame(pd.concat((df.groupby(c, dropna=False).size() for c in cols),  
keys=cols, names=["indices","groups"]))

res = res.rename(columns = {0 : "totals"})
return res

因此,在这种情况下,您可以输入一个数据帧和所选列的列表,也可以只输入相关列的数据帧。

干杯