如何展开并为每个新行保持一定比例的数值 Pandas

How to do explode and keep a fair proportion of number value for each new row Pandas

我有这个数据框:

           A  B 
0  [0, 1, 2]  1 
1        foo  1 
2     [3, 4]  1

我想对“A”列使用分解函数,然后在“B”列的情况下为每个展开的行保持正确和公平的比例。所以结果应该是这样的:

     A  B 
0    0  0.33
0    1  0.33
0    2  0.33
1  foo  1 
2    3  0.5 
2    4  0.5

这可以用爆炸函数实现吗?我会设法用 for row in data.itertuples(): 得出这个结果,但是对于大数据帧,for 循环太慢了。那么您知道如何使用爆炸或其他一些快速方法解决这个问题吗?

如有任何帮助,我将不胜感激。

创建一个布尔掩码,指示 A 包含列表的行:

mask = df['A'].apply(lambda x: isinstance(x, list))

用整数 1 预填充新的分母列(保持除以这些值不变):

df['denom'] = 1

对于 A 是列表的每一行,用列表的长度覆盖 B 的值:

df.loc[mask, 'denom'] = df['A'].str.len()

分解列 A,计算 B 的新值,然后删除 denom:

res = df.explode('A').reset_index(drop=True)
res['B'] = res['B'] / res['denom']
res = res.drop(columns='denom')

结果:

print(res)
     A         B
0    0  0.333333
1    1  0.333333
2    2  0.333333
3  foo  1.000000
4    3  0.500000
5    4  0.500000

可以用explode,然后groupby+apply:

(df.explode('A')
   .assign(B=lambda d: d.groupby(level=0)['B'].apply(lambda s:s/len(s)))
)

输出:

     A         B
0    0  0.333333
0    1  0.333333
0    2  0.333333
1  foo  1.000000
2    4  0.500000
2    5  0.500000

输入:

df = pd.DataFrame({'A': [[0,1,2], 'foo', [4,5]],
                   'B': [1,1,1]})

你可以explode“A”;然后 groupby 索引和 transform count 方法(计算每个索引的数量)并将 'B' 中的元素除以它们对应的索引计数。

out = df.explode('A')
out['B'] /= out['B'].groupby(level=0).transform('count')

输出:

     A         B
0    0  0.333333
0    1  0.333333
0    2  0.333333
1  foo  1.000000
2    3  0.500000
2    4  0.500000