Pandas groupby mean和value_counts,但使用另一列计数

kr98yfug  于 2023-11-15  发布在  其他
关注(0)|答案(1)|浏览(86)

我需要一种内存效率高的方法来分解一个嵌套框,然后按列分组,以获得标准化的value_counts或取决于dtype的平均值。
我有一个类似于这样的框架:

key  cnt X1  X2
0    1    8  a   1
1    1    3  b   0
2    1    4  a   0
3    2    2  b   1
4    2    6  a   0
5    3    3  a   1

字符串
cnt变量表示其他列中值的计数。例如,在第一行中,您可以解释X1具有'a'8示例(即,像['a']*8['a','a','a','a','a','a','a','a'])。
我可以使用.apply(),然后是.explode(),然后是.groupby()来做我需要做的事情,就像这样:

df = pd.DataFrame([[1, 8, 'a', 1], [1, 3, 'b', 0], [1, 4, 'a', 0],
                   [2, 2, 'b', 1], [2, 6, 'a', 0], [3, 3, 'a', 1]],
                  columns=['key', 'cnt', 'X1', 'X2'])

df['X1'] = df.apply(lambda row: [row['X1']] * row['cnt'], axis=1)
df['X2'] = df.apply(lambda row: [row['X2']] * row['cnt'], axis=1)
df = df.explode(['X1', 'X2']).drop(columns=['cnt']).reset_index(drop=True)

vc = pd.DataFrame(df.groupby(['key'])['X1'].value_counts(normalize=True, dropna=True)).unstack()
vc.columns = [f'X1_{col}' for col in vc.columns.get_level_values(1).values]

df = pd.merge(left=vc.reset_index(),
              right=df.drop(columns=['X1']).groupby(['key']).agg('mean').astype(float).reset_index(),
              how='left')
print(df)

   key  X1_a  X1_b        X2
0    1  0.80  0.20  0.533333
1    2  0.75  0.25  0.250000
2    3  1.00   NaN  1.000000


但是我处理的数据是巨大的,有许多不同的变量需要像这样聚合,并且大多数cnt值都>15000,这导致使用过多的内存并冻结我的机器。
我觉得一定有一个更节省内存的方法来做到这一点。有人有什么想法吗?

fcipmucu

fcipmucu1#

有一个更好的方法

计算每个keyX1的归一化计数总和

cnts = pd.crosstab(df['key'], df['X1'], df['cnt'], 
                   aggfunc='sum', normalize='index').add_prefix('X1_')

# X1   X1_a  X1_b
# key            
# 1    0.80  0.20
# 2    0.75  0.25
# 3    1.00  0.00

字符串
计算X2/key的加权平均值

weighted_sum = df['cnt'].mul(df['X2']).groupby(df['key']).sum()
total_weight = df.groupby('key')['cnt'].sum()
average = weighted_sum / total_weight

# key
# 1    0.533333
# 2    0.250000
# 3    1.000000
# dtype: float64


加入我们

result = cnts.join(average.rename('X2'))

#      X1_a  X1_b        X2
# key                      
# 1    0.80  0.20  0.533333
# 2    0.75  0.25  0.250000
# 3    1.00  0.00  1.000000

相关问题