如何展开并为每个新行保持一定比例的数值 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
我有这个数据框:
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