我有以下多索引DataFrame。
import pandas as pd
import numpy as np
# Create df ---
names = ['add', 'sub', 'mul', 'divi'] # List of the names of our maths functions
size = 4
tups = [('scalars', 'add', 'sc0'), ('scalars', 'add', 'sc1'), ('scalars', 'add', 'sc2'), ('scalars', 'sub', 'sc0'), ('scalars', 'sub', 'sc1'), ('scalars', 'mul', 'sc0'), ('scalars', 'mul', 'sc1'), ('scalars', 'mul', 'sc2'), ('scalars', 'divi', 'sc0'), ('scalars', 'divi', 'sc1'), ('operator', '', '')]
df = pd.DataFrame(columns=pd.MultiIndex.from_tuples(tups))
df['operatorIndex'] = np.random.randint(0, len(names), size)
df['operator'] = df['operatorIndex'].apply(lambda x: str(names[x]))
groupSize = 2
df['ID']=np.divmod(np.arange(len(df)),groupSize)[0]+1
df.set_index('ID', inplace=True)
df.sort_index(inplace=True)
> df
scalars operator operatorIndex
add sub mul divi
sc0 sc1 sc2 sc0 sc1 sc0 sc1 sc2 sc0 sc1
ID
1 NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN mul 2
1 NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN add 0
2 NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN sub 1
2 NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN mul 2
如何仅将随机整数(介于0和100之间(分配给与每行的operator
列中的值相关的sc
列?优选地,这将在没有任何循环的情况下进行。
一个例子可能看起来像
> df
scalars operator operatorIndex
add sub mul divi
sc0 sc1 sc2 sc0 sc1 sc0 sc1 sc2 sc0 sc1
ID
1 NaN NaN NaN NaN NaN 7 3 9 NaN NaN mul 2
1 29 12 11 NaN NaN NaN NaN NaN NaN NaN add 0
2 NaN NaN NaN 6 36 NaN NaN NaN NaN NaN sub 1
2 NaN NaN NaN NaN NaN 16 2 29 NaN NaN mul 2
首先,屏蔽第二列级别(df.columns.get_level_values(level=1)
(与运算符列值(df['operator']
(一致的值。这可以通过将两者转换为numpy数组(使用to_numpy
方法(和利用numpy广播来实现。
mask = df.columns.get_level_values(level=1).to_numpy() == df['operator'].to_numpy()[:, None]
然后将此掩码传递给DataFrame.mask
,并使用0到100之间的随机整数更新True值的位置。
res = df.mask(mask, np.random.randint(0, 101, size=df.shape))
输出
# Given the input df
>>> df
scalars operator operatorIndex
add sub mul divi
sc0 sc1 sc2 sc0 sc1 sc0 sc1 sc2 sc0 sc1
ID
1 NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN mul 2
1 NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN add 0
2 NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN sub 1
2 NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN mul 2
>>> mask
[[False False False False False True True True False False False False]
[ True True True False False False False False False False False False]
[False False False True True False False False False False False False]
[False False False False False True True True False False False False]]
>>> res
add sub mul divi
sc0 sc1 sc2 sc0 sc1 sc0 sc1 sc2 sc0 sc1
ID
1 NaN NaN NaN NaN NaN 2 79 17 NaN NaN mul 2
1 15 16 30 NaN NaN NaN NaN NaN NaN NaN add 0
2 NaN NaN NaN 35 94 NaN NaN NaN NaN NaN sub 1
2 NaN NaN NaN NaN NaN 11 95 48 NaN NaN mul 2